LocationAndNavigationService.h 3.03 KB
#ifndef __BLE_LOCATION_AND_NAVIGATION_SERVICE_H__
#define __BLE_LOCATION_AND_NAVIGATION_SERVICE_H__

#include "BLEDevice.h"

/**
* @class LocationAndNavigationService
* @brief BLE Location and Navigation Service. This service provides location.
* Service:  https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.location_and_navigation.xml
* LN Feature:  https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.ln_feature.xml
* Location and Speed:  https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.location_and_speed.xml
*/
class LocationAndNavigationService {
public:
    const static uint16_t UUID_LOCATION_AND_NAVIGATION_SERVICE = 0x1819;
    const static uint16_t UUID_LN_FEATURE_CHAR = 0x2A6A;
    const static uint16_t UUID_LOCATION_AND_SPEED_CHAR = 0x2A67;
    
    typedef struct LocationAndSpeedType_t{ 
        uint16_t flags;
        int32_t latitude;
        int32_t longitude;
        int32_t altitude;
    }  LocationAndSpeedType_t;
    typedef uint32_t LNFeatureType_t;

    /**
     * @brief   LocationAndNavigationService constructor.
     * @param   ble Reference to BLE device.
     */
    LocationAndNavigationService(BLEDevice& _ble, LNFeatureType_t features) :
        ble(_ble),
        lnFeature(features),
        lnFeatureCharacteristic(UUID_LN_FEATURE_CHAR, &lnFeature),
        locationAndSpeedCharacteristic(UUID_LOCATION_AND_SPEED_CHAR, &locationAndSpeed, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)
    {
        static bool serviceAdded = false; /* We should only ever need to add the information service once. */
        if (serviceAdded) {
            return;
        }

        GattCharacteristic *charTable[] = { &lnFeatureCharacteristic,
                                            &locationAndSpeedCharacteristic };

        GattService locationAndNavigationService(UUID_LOCATION_AND_NAVIGATION_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));

        ble.addService(locationAndNavigationService);
        serviceAdded = true;
    }

    /**
     * @brief   Update location and speed characteristic.
     * @param   newLocationAndSpeedVal New location and speed measurement.
     */
    void updateLocationAndSpeed(uint16_t flags, double latitude, double longitude, double altitude)
    {
        locationAndSpeed = (LocationAndSpeedType_t) {
            (uint16_t)flags,
            (int32_t)(latitude * 100000),
            (int32_t)(longitude * 100000),
            (int32_t)(altitude * 100)
        };
        ble.updateCharacteristicValue(locationAndSpeedCharacteristic.getValueHandle(), (uint8_t *) &locationAndSpeed, sizeof(LocationAndSpeedType_t));
    }

private:
    BLEDevice& ble;

    LNFeatureType_t lnFeature;
    LocationAndSpeedType_t    locationAndSpeed;

    ReadOnlyGattCharacteristic<LNFeatureType_t> lnFeatureCharacteristic;
    ReadOnlyGattCharacteristic<LocationAndSpeedType_t> locationAndSpeedCharacteristic;
};

#endif /* #ifndef __BLE_LOCATION_AND_NAVIGATION_SERVICE_H__*/