Yoshio Miyakawa / Mbed 2 deprecated BLE_CyclingSpeedAndCadence

Dependencies:   BLE_API mbed nRF51822

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CyclingSpeedAndCadenceService.h Source File

CyclingSpeedAndCadenceService.h

00001 /*
00002 Copyright (c) 2016 Y. Miyakawa
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
00005 and associated documentation files (the "Software"), to deal in the Software without restriction, 
00006 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
00007 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
00008 subject to the following conditions:
00009 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
00010 
00011 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
00012 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
00013 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 
00014 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
00015 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00016 */
00017 
00018 #ifndef __BLE_CYCLING_SPEED_AND_CADENCE_SERVICE_H__
00019 #define __BLE_CYCLING_SPEED_AND_CADENCE_SERVICE_H__
00020 
00021 #include "ble/BLE.h"
00022 
00023 #define UUID_SENSOR_LOCATION_CHAR   0x2A5D
00024 #define UUID_CSC_CONTROL_POINT_CHAR 0x2A55
00025 
00026 
00027 /**
00028 * @class CyclingSpeedAndCadenceService
00029 * @brief BLE Service for Cycling Speed and Cadence. <br>
00030 * Service:  https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.cycling_speed_and_cadence.xml <br>
00031 * CyclingSpeedAndCadenceService Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.csc_measurement.xml <br>
00032 * Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.sensor_location.xml
00033 */
00034 class CyclingSpeedAndCadenceService {
00035 public:
00036     enum {
00037         LOCATION_OTHER = 0,
00038         LOCATION_TOP_OF_SHOE,
00039         LOCATION_IN_SHOE,
00040         LOCATION_HIP,
00041         LOCATION_FRONT_WHEEL,
00042         LOCATION_LEFT_CRANK,
00043         LOCATION_RIGHT_CRANK,
00044         LOCATION_LEFT_PEDAL,
00045         LOCATION_RIGHT_PEDAL,
00046         LOCATION_FRONT_HUB,
00047         LOCATION_REAR_DROPOUT,
00048         LOCATION_CHAINSTAY,
00049         LOCATION_REAR_WHEEL,
00050         LOCATION_REAR_HUB,
00051         LOCATION_CHEST,
00052     };
00053 
00054     enum {
00055         FEATURE_WHEEL_REVOLUTION_DATA      = 0x0001,
00056         FEATURE_CRANK_REVOLUTION_DATA      = 0x0002,
00057         FEATURE_MULTIPLE_SENSOR_LOCATIONS  = 0x0004,
00058     };
00059 
00060     enum {
00061         FLAG_WHEEL_REVOLUTION_DATA_PRESENT = 0x01,
00062         FLAG_CRANK_REVOLUTION_DATA_PRESENT = 0x02,
00063     };
00064 
00065     enum {
00066         OPCODE_SET_CUMULATIVE_VALUE               =  1,
00067         OPCODE_START_SENSOR_CALIBRATION           =  2,
00068         OPCODE_UPDATE_SENSOR_LOCATION             =  3,
00069         OPCODE_REQUEST_SUPPORTED_SENSOR_LOCATIONS =  4,
00070         OPCODE_RESPONSE_CODE                      = 16,
00071     };
00072 
00073     enum {
00074         RESPONSE_SUCCESS               = 1,
00075         RESPONSE_OP_CODE_NOT_SUPPORTED = 2,
00076         RESPONSE_INVALID_PARAMETER     = 3,
00077         RESPONSE_OPERATION_FAILED      = 4,
00078     };
00079 
00080 public:
00081     CyclingSpeedAndCadenceService(BLE &_ble, uint16_t feature, uint8_t location) :
00082         ble(_ble),
00083         cyclingSpeedAndCadenceMeasurement(GattCharacteristic::UUID_CSC_MEASUREMENT_CHAR, measureData,
00084                        MAX_MEASURE_BYTES, MAX_MEASURE_BYTES,
00085                        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
00086         cyclingSpeedAndCadenceControlPoint(UUID_CSC_CONTROL_POINT_CHAR, controlData,
00087                        MAX_CONTROL_BYTES, MAX_CONTROL_BYTES,
00088                        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE),
00089         cyclingSpeedAndCadenceFeature(GattCharacteristic::UUID_CSC_FEATURE_CHAR, &feature),
00090         cyclingSpeedAndCadenceLocation(UUID_SENSOR_LOCATION_CHAR, &location) {
00091         setupService();
00092     }
00093 
00094     void updateCyclingSpeedAndCadence(uint8_t flags, uint16_t dnw, uint16_t dtw, uint16_t dnc, uint16_t dtc) {
00095         cumulativeWheelRev += dnw;
00096         lastWheelEventTime += dtw;
00097         cumulativeCrankRev += dnc;
00098         lastCrankEventTime += dtc;
00099 
00100         unsigned i = 0;
00101         measureData[i++] = flags;
00102 
00103         if (flags & FLAG_WHEEL_REVOLUTION_DATA_PRESENT) {
00104             measureData[i++] = (uint8_t)(cumulativeWheelRev & 0xFF);
00105             measureData[i++] = (uint8_t)((cumulativeWheelRev >>  8) & 0xFF);
00106             measureData[i++] = (uint8_t)((cumulativeWheelRev >> 16) & 0xFF);
00107             measureData[i++] = (uint8_t)((cumulativeWheelRev >> 24) & 0xFF);
00108 
00109             measureData[i++] = (uint8_t)(lastWheelEventTime & 0xFF);
00110             measureData[i++] = (uint8_t)(lastWheelEventTime >> 8);
00111         }
00112         if (flags & FLAG_CRANK_REVOLUTION_DATA_PRESENT) {
00113             measureData[i++] = (uint8_t)(cumulativeCrankRev & 0xFF);
00114             measureData[i++] = (uint8_t)(cumulativeCrankRev >> 8);
00115 
00116             measureData[i++] = (uint8_t)(lastCrankEventTime & 0xFF);
00117             measureData[i++] = (uint8_t)(lastCrankEventTime >> 8);
00118         }
00119         unsigned nbyte = i;
00120         ble.updateCharacteristicValue(cyclingSpeedAndCadenceMeasurement.getValueAttribute().getHandle(), measureData, nbyte);
00121     }
00122 
00123     void indicateResponse(uint8_t opCode, uint8_t responseValue) {
00124         controlData[0] = OPCODE_RESPONSE_CODE;
00125         controlData[1] = opCode;
00126         controlData[2] = responseValue;
00127         unsigned nbyte = 3;
00128         ble.updateCharacteristicValue(cyclingSpeedAndCadenceControlPoint.getValueAttribute().getHandle(), controlData, nbyte);
00129     }
00130 
00131     void indicateResponse(uint8_t opCode, uint8_t responseValue, uint8_t responseParameter) {
00132         controlData[0] = OPCODE_RESPONSE_CODE;
00133         controlData[1] = opCode;
00134         controlData[2] = responseValue;
00135         controlData[3] = responseParameter;
00136         unsigned nbyte = 4;
00137         ble.updateCharacteristicValue(cyclingSpeedAndCadenceControlPoint.getValueAttribute().getHandle(), controlData, nbyte);
00138     }
00139 
00140     virtual void onDataWritten(const GattWriteCallbackParams *params) {
00141         if (params->handle == cyclingSpeedAndCadenceControlPoint.getValueAttribute().getHandle()) {
00142             uint32_t uu;
00143             uint8_t opCode = params->data[0];
00144             switch(opCode) {
00145             case OPCODE_SET_CUMULATIVE_VALUE:
00146                 uu  = params->data[4];
00147                 uu *= 256;
00148                 uu += params->data[3];
00149                 uu *= 256;
00150                 uu += params->data[2];
00151                 uu *= 256;
00152                 uu += params->data[1];
00153                 cumulativeWheelRev = uu;
00154                 indicateResponse(opCode, CyclingSpeedAndCadenceService::RESPONSE_SUCCESS);
00155                 break;
00156             default:
00157                 indicateResponse(opCode, CyclingSpeedAndCadenceService::RESPONSE_OP_CODE_NOT_SUPPORTED);
00158             }
00159         }
00160     }
00161 
00162 protected:
00163     void setupService(void) {
00164         cumulativeWheelRev = 0;
00165         lastWheelEventTime = 0;
00166         cumulativeCrankRev = 0;
00167         lastCrankEventTime = 0;
00168 
00169         GattCharacteristic *charTable[] = {&cyclingSpeedAndCadenceMeasurement, &cyclingSpeedAndCadenceFeature, &cyclingSpeedAndCadenceLocation, &cyclingSpeedAndCadenceControlPoint};
00170         GattService         cyclingSpeedAndCadenceService(GattService::UUID_CYCLING_SPEED_AND_CADENCE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
00171 
00172         ble.addService(cyclingSpeedAndCadenceService);
00173         ble.onDataWritten(this, &CyclingSpeedAndCadenceService::onDataWritten);
00174     }
00175 
00176 protected:
00177     BLE &ble;
00178 
00179     GattCharacteristic                   cyclingSpeedAndCadenceMeasurement;
00180     GattCharacteristic                   cyclingSpeedAndCadenceControlPoint;
00181     ReadOnlyGattCharacteristic<uint16_t> cyclingSpeedAndCadenceFeature;
00182     ReadOnlyGattCharacteristic<uint8_t>  cyclingSpeedAndCadenceLocation;
00183 
00184     static const unsigned MAX_MEASURE_BYTES  = 11;
00185     static const unsigned MAX_CONTROL_BYTES  = 4;
00186 
00187     uint8_t measureData[MAX_MEASURE_BYTES];
00188     uint8_t controlData[MAX_CONTROL_BYTES];
00189 
00190     uint32_t cumulativeWheelRev;
00191     uint16_t lastWheelEventTime;
00192     uint16_t cumulativeCrankRev;
00193     uint16_t lastCrankEventTime;
00194 };
00195 
00196 #endif /* #ifndef __BLE_CYCLING_SPEED_AND_CADENCE_SERVICE_H__*/