Pinned to some recent date

Committer:
Simon Cooksey
Date:
Thu Nov 17 16:43:53 2016 +0000
Revision:
0:fb7af294d5d9
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Simon Cooksey 0:fb7af294d5d9 1 /* mbed Microcontroller Library
Simon Cooksey 0:fb7af294d5d9 2 * Copyright (c) 2006-2013 ARM Limited
Simon Cooksey 0:fb7af294d5d9 3 *
Simon Cooksey 0:fb7af294d5d9 4 * Licensed under the Apache License, Version 2.0 (the "License");
Simon Cooksey 0:fb7af294d5d9 5 * you may not use this file except in compliance with the License.
Simon Cooksey 0:fb7af294d5d9 6 * You may obtain a copy of the License at
Simon Cooksey 0:fb7af294d5d9 7 *
Simon Cooksey 0:fb7af294d5d9 8 * http://www.apache.org/licenses/LICENSE-2.0
Simon Cooksey 0:fb7af294d5d9 9 *
Simon Cooksey 0:fb7af294d5d9 10 * Unless required by applicable law or agreed to in writing, software
Simon Cooksey 0:fb7af294d5d9 11 * distributed under the License is distributed on an "AS IS" BASIS,
Simon Cooksey 0:fb7af294d5d9 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Simon Cooksey 0:fb7af294d5d9 13 * See the License for the specific language governing permissions and
Simon Cooksey 0:fb7af294d5d9 14 * limitations under the License.
Simon Cooksey 0:fb7af294d5d9 15 */
Simon Cooksey 0:fb7af294d5d9 16
Simon Cooksey 0:fb7af294d5d9 17 #ifdef TARGET_NRF51822 /* DFU only supported on nrf51 platforms */
Simon Cooksey 0:fb7af294d5d9 18
Simon Cooksey 0:fb7af294d5d9 19 #ifndef __BLE_DFU_SERVICE_H__
Simon Cooksey 0:fb7af294d5d9 20 #define __BLE_DFU_SERVICE_H__
Simon Cooksey 0:fb7af294d5d9 21
Simon Cooksey 0:fb7af294d5d9 22 #include "ble/BLE.h"
Simon Cooksey 0:fb7af294d5d9 23 #include "ble/UUID.h"
Simon Cooksey 0:fb7af294d5d9 24
Simon Cooksey 0:fb7af294d5d9 25 extern "C" {
Simon Cooksey 0:fb7af294d5d9 26 #include "dfu_app_handler.h"
Simon Cooksey 0:fb7af294d5d9 27 }
Simon Cooksey 0:fb7af294d5d9 28
Simon Cooksey 0:fb7af294d5d9 29 extern const uint8_t DFUServiceBaseUUID[];
Simon Cooksey 0:fb7af294d5d9 30 extern const uint16_t DFUServiceShortUUID;
Simon Cooksey 0:fb7af294d5d9 31 extern const uint16_t DFUServiceControlCharacteristicShortUUID;
Simon Cooksey 0:fb7af294d5d9 32
Simon Cooksey 0:fb7af294d5d9 33 extern const uint8_t DFUServiceUUID[];
Simon Cooksey 0:fb7af294d5d9 34 extern const uint8_t DFUServiceControlCharacteristicUUID[];
Simon Cooksey 0:fb7af294d5d9 35 extern const uint8_t DFUServicePacketCharacteristicUUID[];
Simon Cooksey 0:fb7af294d5d9 36
Simon Cooksey 0:fb7af294d5d9 37 /**
Simon Cooksey 0:fb7af294d5d9 38 * @class DFUService
Simon Cooksey 0:fb7af294d5d9 39 * @brief Device Firmware Update Service.
Simon Cooksey 0:fb7af294d5d9 40 */
Simon Cooksey 0:fb7af294d5d9 41 class DFUService {
Simon Cooksey 0:fb7af294d5d9 42 public:
Simon Cooksey 0:fb7af294d5d9 43 /**
Simon Cooksey 0:fb7af294d5d9 44 * @brief Signature for the handover callback. The application may provide this
Simon Cooksey 0:fb7af294d5d9 45 * callback when setting up the DFU service. The callback is then
Simon Cooksey 0:fb7af294d5d9 46 * invoked before handing control over to the bootloader.
Simon Cooksey 0:fb7af294d5d9 47 */
Simon Cooksey 0:fb7af294d5d9 48 typedef void (*ResetPrepare_t)(void);
Simon Cooksey 0:fb7af294d5d9 49
Simon Cooksey 0:fb7af294d5d9 50 public:
Simon Cooksey 0:fb7af294d5d9 51 /**
Simon Cooksey 0:fb7af294d5d9 52 * @brief Adds Device Firmware Update Service to an existing BLE object.
Simon Cooksey 0:fb7af294d5d9 53 *
Simon Cooksey 0:fb7af294d5d9 54 * @param[ref] _ble
Simon Cooksey 0:fb7af294d5d9 55 * BLE object for the underlying controller.
Simon Cooksey 0:fb7af294d5d9 56 * @param[in] _handoverCallback
Simon Cooksey 0:fb7af294d5d9 57 * Application-specific handover callback.
Simon Cooksey 0:fb7af294d5d9 58 */
Simon Cooksey 0:fb7af294d5d9 59 DFUService(BLE &_ble, ResetPrepare_t _handoverCallback = NULL) :
Simon Cooksey 0:fb7af294d5d9 60 ble(_ble),
Simon Cooksey 0:fb7af294d5d9 61 controlPoint(DFUServiceControlCharacteristicUUID, controlBytes, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
Simon Cooksey 0:fb7af294d5d9 62 packet(DFUServicePacketCharacteristicUUID, packetBytes, SIZEOF_PACKET_BYTES, SIZEOF_PACKET_BYTES,
Simon Cooksey 0:fb7af294d5d9 63 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE),
Simon Cooksey 0:fb7af294d5d9 64 controlBytes(),
Simon Cooksey 0:fb7af294d5d9 65 packetBytes() {
Simon Cooksey 0:fb7af294d5d9 66 static bool serviceAdded = false; /* We only add the DFU service once. */
Simon Cooksey 0:fb7af294d5d9 67 if (serviceAdded) {
Simon Cooksey 0:fb7af294d5d9 68 return;
Simon Cooksey 0:fb7af294d5d9 69 }
Simon Cooksey 0:fb7af294d5d9 70
Simon Cooksey 0:fb7af294d5d9 71 /* Set an initial value for control bytes, so that the application's DFU service can
Simon Cooksey 0:fb7af294d5d9 72 * be distinguished from the real DFU service provided by the bootloader. */
Simon Cooksey 0:fb7af294d5d9 73 controlBytes[0] = 0xFF;
Simon Cooksey 0:fb7af294d5d9 74 controlBytes[1] = 0xFF;
Simon Cooksey 0:fb7af294d5d9 75
Simon Cooksey 0:fb7af294d5d9 76 GattCharacteristic *dfuChars[] = {&controlPoint, &packet};
Simon Cooksey 0:fb7af294d5d9 77 GattService dfuService(DFUServiceUUID, dfuChars, sizeof(dfuChars) / sizeof(GattCharacteristic *));
Simon Cooksey 0:fb7af294d5d9 78
Simon Cooksey 0:fb7af294d5d9 79 ble.addService(dfuService);
Simon Cooksey 0:fb7af294d5d9 80 handoverCallback = _handoverCallback;
Simon Cooksey 0:fb7af294d5d9 81 serviceAdded = true;
Simon Cooksey 0:fb7af294d5d9 82
Simon Cooksey 0:fb7af294d5d9 83 ble.onDataWritten(this, &DFUService::onDataWritten);
Simon Cooksey 0:fb7af294d5d9 84 }
Simon Cooksey 0:fb7af294d5d9 85
Simon Cooksey 0:fb7af294d5d9 86 /**
Simon Cooksey 0:fb7af294d5d9 87 * @brief Get the handle for the value attribute of the control characteristic.
Simon Cooksey 0:fb7af294d5d9 88 */
Simon Cooksey 0:fb7af294d5d9 89 uint16_t getControlHandle(void) const {
Simon Cooksey 0:fb7af294d5d9 90 return controlPoint.getValueHandle();
Simon Cooksey 0:fb7af294d5d9 91 }
Simon Cooksey 0:fb7af294d5d9 92
Simon Cooksey 0:fb7af294d5d9 93 /**
Simon Cooksey 0:fb7af294d5d9 94 * @brief This callback allows the DFU service to receive the initial trigger to
Simon Cooksey 0:fb7af294d5d9 95 * hand control over to the bootloader. First, the application is given a
Simon Cooksey 0:fb7af294d5d9 96 * chance to clean up.
Simon Cooksey 0:fb7af294d5d9 97 *
Simon Cooksey 0:fb7af294d5d9 98 * @param[in] params
Simon Cooksey 0:fb7af294d5d9 99 * Information about the characterisitc being updated.
Simon Cooksey 0:fb7af294d5d9 100 */
Simon Cooksey 0:fb7af294d5d9 101 virtual void onDataWritten(const GattWriteCallbackParams *params) {
Simon Cooksey 0:fb7af294d5d9 102 if (params->handle == controlPoint.getValueHandle()) {
Simon Cooksey 0:fb7af294d5d9 103 /* At present, writing anything will do the trick - this needs to be improved. */
Simon Cooksey 0:fb7af294d5d9 104 if (handoverCallback) {
Simon Cooksey 0:fb7af294d5d9 105 handoverCallback();
Simon Cooksey 0:fb7af294d5d9 106 }
Simon Cooksey 0:fb7af294d5d9 107
Simon Cooksey 0:fb7af294d5d9 108 // Call bootloader_start implicitly trough a event handler call
Simon Cooksey 0:fb7af294d5d9 109 // it is a work around for bootloader_start not being public in sdk 8.1
Simon Cooksey 0:fb7af294d5d9 110 ble_dfu_t p_dfu;
Simon Cooksey 0:fb7af294d5d9 111 ble_dfu_evt_t p_evt;
Simon Cooksey 0:fb7af294d5d9 112
Simon Cooksey 0:fb7af294d5d9 113 p_dfu.conn_handle = params->connHandle;
Simon Cooksey 0:fb7af294d5d9 114 p_evt.ble_dfu_evt_type = BLE_DFU_START;
Simon Cooksey 0:fb7af294d5d9 115
Simon Cooksey 0:fb7af294d5d9 116 dfu_app_on_dfu_evt(&p_dfu, &p_evt);
Simon Cooksey 0:fb7af294d5d9 117 }
Simon Cooksey 0:fb7af294d5d9 118 }
Simon Cooksey 0:fb7af294d5d9 119
Simon Cooksey 0:fb7af294d5d9 120 protected:
Simon Cooksey 0:fb7af294d5d9 121 static const unsigned SIZEOF_CONTROL_BYTES = 2;
Simon Cooksey 0:fb7af294d5d9 122 static const unsigned SIZEOF_PACKET_BYTES = 20;
Simon Cooksey 0:fb7af294d5d9 123
Simon Cooksey 0:fb7af294d5d9 124 protected:
Simon Cooksey 0:fb7af294d5d9 125 BLE &ble;
Simon Cooksey 0:fb7af294d5d9 126
Simon Cooksey 0:fb7af294d5d9 127 /**< Writing to the control characteristic triggers the handover to DFU
Simon Cooksey 0:fb7af294d5d9 128 * bootloader. At present, writing anything will do the trick - this needs
Simon Cooksey 0:fb7af294d5d9 129 * to be improved. */
Simon Cooksey 0:fb7af294d5d9 130 WriteOnlyArrayGattCharacteristic<uint8_t, SIZEOF_CONTROL_BYTES> controlPoint;
Simon Cooksey 0:fb7af294d5d9 131
Simon Cooksey 0:fb7af294d5d9 132 /**< The packet characteristic in this service doesn't do anything meaningful;
Simon Cooksey 0:fb7af294d5d9 133 * it is only a placeholder to mimic the corresponding characteristic in the
Simon Cooksey 0:fb7af294d5d9 134 * actual DFU service implemented by the bootloader. Without this, some
Simon Cooksey 0:fb7af294d5d9 135 * FOTA clients might get confused, because service definitions change after
Simon Cooksey 0:fb7af294d5d9 136 * handing control over to the bootloader. */
Simon Cooksey 0:fb7af294d5d9 137 GattCharacteristic packet;
Simon Cooksey 0:fb7af294d5d9 138
Simon Cooksey 0:fb7af294d5d9 139 uint8_t controlBytes[SIZEOF_CONTROL_BYTES];
Simon Cooksey 0:fb7af294d5d9 140 uint8_t packetBytes[SIZEOF_PACKET_BYTES];
Simon Cooksey 0:fb7af294d5d9 141
Simon Cooksey 0:fb7af294d5d9 142 static ResetPrepare_t handoverCallback; /**< Application-specific handover callback. */
Simon Cooksey 0:fb7af294d5d9 143 };
Simon Cooksey 0:fb7af294d5d9 144
Simon Cooksey 0:fb7af294d5d9 145 #endif /* #ifndef __BLE_DFU_SERVICE_H__*/
Simon Cooksey 0:fb7af294d5d9 146 #endif /* #ifdef TARGET_NRF51822 */