Preliminary main mbed library for nexpaq development
Diff: features/FEATURE_BLE/ble/services/DFUService.h
- Revision:
- 0:6c56fb4bc5f0
diff -r 000000000000 -r 6c56fb4bc5f0 features/FEATURE_BLE/ble/services/DFUService.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/features/FEATURE_BLE/ble/services/DFUService.h Fri Nov 04 20:27:58 2016 +0000 @@ -0,0 +1,146 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef TARGET_NRF51822 /* DFU only supported on nrf51 platforms */ + +#ifndef __BLE_DFU_SERVICE_H__ +#define __BLE_DFU_SERVICE_H__ + +#include "ble/BLE.h" +#include "ble/UUID.h" + +extern "C" { +#include "dfu_app_handler.h" +} + +extern const uint8_t DFUServiceBaseUUID[]; +extern const uint16_t DFUServiceShortUUID; +extern const uint16_t DFUServiceControlCharacteristicShortUUID; + +extern const uint8_t DFUServiceUUID[]; +extern const uint8_t DFUServiceControlCharacteristicUUID[]; +extern const uint8_t DFUServicePacketCharacteristicUUID[]; + +/** +* @class DFUService +* @brief Device Firmware Update Service. +*/ +class DFUService { +public: + /** + * @brief Signature for the handover callback. The application may provide this + * callback when setting up the DFU service. The callback is then + * invoked before handing control over to the bootloader. + */ + typedef void (*ResetPrepare_t)(void); + +public: + /** + * @brief Adds Device Firmware Update Service to an existing BLE object. + * + * @param[ref] _ble + * BLE object for the underlying controller. + * @param[in] _handoverCallback + * Application-specific handover callback. + */ + DFUService(BLE &_ble, ResetPrepare_t _handoverCallback = NULL) : + ble(_ble), + controlPoint(DFUServiceControlCharacteristicUUID, controlBytes, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), + packet(DFUServicePacketCharacteristicUUID, packetBytes, SIZEOF_PACKET_BYTES, SIZEOF_PACKET_BYTES, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE), + controlBytes(), + packetBytes() { + static bool serviceAdded = false; /* We only add the DFU service once. */ + if (serviceAdded) { + return; + } + + /* Set an initial value for control bytes, so that the application's DFU service can + * be distinguished from the real DFU service provided by the bootloader. */ + controlBytes[0] = 0xFF; + controlBytes[1] = 0xFF; + + GattCharacteristic *dfuChars[] = {&controlPoint, &packet}; + GattService dfuService(DFUServiceUUID, dfuChars, sizeof(dfuChars) / sizeof(GattCharacteristic *)); + + ble.addService(dfuService); + handoverCallback = _handoverCallback; + serviceAdded = true; + + ble.onDataWritten(this, &DFUService::onDataWritten); + } + + /** + * @brief Get the handle for the value attribute of the control characteristic. + */ + uint16_t getControlHandle(void) const { + return controlPoint.getValueHandle(); + } + + /** + * @brief This callback allows the DFU service to receive the initial trigger to + * hand control over to the bootloader. First, the application is given a + * chance to clean up. + * + * @param[in] params + * Information about the characterisitc being updated. + */ + virtual void onDataWritten(const GattWriteCallbackParams *params) { + if (params->handle == controlPoint.getValueHandle()) { + /* At present, writing anything will do the trick - this needs to be improved. */ + if (handoverCallback) { + handoverCallback(); + } + + // Call bootloader_start implicitly trough a event handler call + // it is a work around for bootloader_start not being public in sdk 8.1 + ble_dfu_t p_dfu; + ble_dfu_evt_t p_evt; + + p_dfu.conn_handle = params->connHandle; + p_evt.ble_dfu_evt_type = BLE_DFU_START; + + dfu_app_on_dfu_evt(&p_dfu, &p_evt); + } + } + +protected: + static const unsigned SIZEOF_CONTROL_BYTES = 2; + static const unsigned SIZEOF_PACKET_BYTES = 20; + +protected: + BLE &ble; + + /**< Writing to the control characteristic triggers the handover to DFU + * bootloader. At present, writing anything will do the trick - this needs + * to be improved. */ + WriteOnlyArrayGattCharacteristic<uint8_t, SIZEOF_CONTROL_BYTES> controlPoint; + + /**< The packet characteristic in this service doesn't do anything meaningful; + * it is only a placeholder to mimic the corresponding characteristic in the + * actual DFU service implemented by the bootloader. Without this, some + * FOTA clients might get confused, because service definitions change after + * handing control over to the bootloader. */ + GattCharacteristic packet; + + uint8_t controlBytes[SIZEOF_CONTROL_BYTES]; + uint8_t packetBytes[SIZEOF_PACKET_BYTES]; + + static ResetPrepare_t handoverCallback; /**< Application-specific handover callback. */ +}; + +#endif /* #ifndef __BLE_DFU_SERVICE_H__*/ +#endif /* #ifdef TARGET_NRF51822 */