BLE_API_Tiny_BLE

Dependents:   CSSE4011_BLE_IMU

Fork of BLE_API by Bluetooth Low Energy

Committer:
Rohit Grover
Date:
Fri Sep 26 14:28:59 2014 +0100
Revision:
119:18684018b83e
Parent:
118:620d28e7a1ba
Child:
120:467527c1b943
Add the packet characteristic to the DFU Service.

This helps mimic the layout of the actual DFU service in the
dfu-bootloader. Without this, some FOTA clients might get confused as
service definitions change after handing control over to the
bootloader.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rohit Grover 118:620d28e7a1ba 1 /* mbed Microcontroller Library
Rohit Grover 118:620d28e7a1ba 2 * Copyright (c) 2006-2013 ARM Limited
Rohit Grover 118:620d28e7a1ba 3 *
Rohit Grover 118:620d28e7a1ba 4 * Licensed under the Apache License, Version 2.0 (the "License");
Rohit Grover 118:620d28e7a1ba 5 * you may not use this file except in compliance with the License.
Rohit Grover 118:620d28e7a1ba 6 * You may obtain a copy of the License at
Rohit Grover 118:620d28e7a1ba 7 *
Rohit Grover 118:620d28e7a1ba 8 * http://www.apache.org/licenses/LICENSE-2.0
Rohit Grover 118:620d28e7a1ba 9 *
Rohit Grover 118:620d28e7a1ba 10 * Unless required by applicable law or agreed to in writing, software
Rohit Grover 118:620d28e7a1ba 11 * distributed under the License is distributed on an "AS IS" BASIS,
Rohit Grover 118:620d28e7a1ba 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Rohit Grover 118:620d28e7a1ba 13 * See the License for the specific language governing permissions and
Rohit Grover 118:620d28e7a1ba 14 * limitations under the License.
Rohit Grover 118:620d28e7a1ba 15 */
Rohit Grover 118:620d28e7a1ba 16
Rohit Grover 118:620d28e7a1ba 17 #ifndef __BLE_DFU_SERVICE_H__
Rohit Grover 118:620d28e7a1ba 18 #define __BLE_DFU_SERVICE_H__
Rohit Grover 118:620d28e7a1ba 19
Rohit Grover 118:620d28e7a1ba 20 #include "BLEDevice.h"
Rohit Grover 118:620d28e7a1ba 21 #include "UUID.h"
Rohit Grover 118:620d28e7a1ba 22
Rohit Grover 118:620d28e7a1ba 23 extern "C" void bootloader_start(void);
Rohit Grover 118:620d28e7a1ba 24
Rohit Grover 118:620d28e7a1ba 25 extern const uint8_t DFUServiceBaseUUID[];
Rohit Grover 118:620d28e7a1ba 26 extern const uint16_t DFUServiceShortUUID;
Rohit Grover 118:620d28e7a1ba 27 extern const uint16_t DFUServiceControlCharacteristicShortUUID;
Rohit Grover 118:620d28e7a1ba 28
Rohit Grover 118:620d28e7a1ba 29 extern const uint8_t DFUServiceUUID[];
Rohit Grover 118:620d28e7a1ba 30 extern const uint8_t DFUServiceControlCharacteristicUUID[];
Rohit Grover 119:18684018b83e 31 extern const uint8_t DFUServicePacketCharacteristicUUID[];
Rohit Grover 118:620d28e7a1ba 32
Rohit Grover 118:620d28e7a1ba 33 class DFUService {
Rohit Grover 118:620d28e7a1ba 34 public:
Rohit Grover 118:620d28e7a1ba 35 /**
Rohit Grover 118:620d28e7a1ba 36 * Signature for the handover callback. The application may provide such a
Rohit Grover 118:620d28e7a1ba 37 * callback when setting up the DFU service, in which case it will be
Rohit Grover 119:18684018b83e 38 * invoked before handing control over to the bootloader.
Rohit Grover 118:620d28e7a1ba 39 */
Rohit Grover 118:620d28e7a1ba 40 typedef void (*ResetPrepare_t)(void);
Rohit Grover 118:620d28e7a1ba 41
Rohit Grover 118:620d28e7a1ba 42 public:
Rohit Grover 118:620d28e7a1ba 43 DFUService(BLEDevice &_ble, ResetPrepare_t _handoverCallback = NULL) :
Rohit Grover 118:620d28e7a1ba 44 ble(_ble),
Rohit Grover 118:620d28e7a1ba 45 controlBytes(),
Rohit Grover 118:620d28e7a1ba 46 controlPoint(DFUServiceControlCharacteristicUUID, controlBytes, SIZEOF_CONTROL_BYTES, SIZEOF_CONTROL_BYTES,
Rohit Grover 119:18684018b83e 47 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
Rohit Grover 119:18684018b83e 48 packet(DFUServicePacketCharacteristicUUID, packetBytes, SIZEOF_PACKET_BYTES, SIZEOF_PACKET_BYTES,
Rohit Grover 119:18684018b83e 49 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE) {
Rohit Grover 118:620d28e7a1ba 50 static bool serviceAdded = false; /* We should only ever need to add the DFU service once. */
Rohit Grover 118:620d28e7a1ba 51 if (serviceAdded) {
Rohit Grover 118:620d28e7a1ba 52 return;
Rohit Grover 118:620d28e7a1ba 53 }
Rohit Grover 118:620d28e7a1ba 54
Rohit Grover 119:18684018b83e 55 GattCharacteristic *dfuChars[] = {&controlPoint, &packet};
Rohit Grover 118:620d28e7a1ba 56 GattService dfuService(DFUServiceUUID, dfuChars, sizeof(dfuChars) / sizeof(GattCharacteristic *));
Rohit Grover 118:620d28e7a1ba 57
Rohit Grover 118:620d28e7a1ba 58 ble.addService(dfuService);
Rohit Grover 118:620d28e7a1ba 59 handoverCallback = _handoverCallback;
Rohit Grover 118:620d28e7a1ba 60 serviceAdded = true;
Rohit Grover 118:620d28e7a1ba 61
Rohit Grover 118:620d28e7a1ba 62 ble.onDataWritten(this, &DFUService::onDataWritten);
Rohit Grover 118:620d28e7a1ba 63 }
Rohit Grover 118:620d28e7a1ba 64
Rohit Grover 118:620d28e7a1ba 65 uint16_t getControlHandle(void) {
Rohit Grover 118:620d28e7a1ba 66 return controlPoint.getValueAttribute().getHandle();
Rohit Grover 118:620d28e7a1ba 67 }
Rohit Grover 118:620d28e7a1ba 68
Rohit Grover 118:620d28e7a1ba 69 /**
Rohit Grover 118:620d28e7a1ba 70 * This callback allows the DFU service to receive the initial trigger to
Rohit Grover 118:620d28e7a1ba 71 * handover control to the bootloader; but first the application is given a
Rohit Grover 118:620d28e7a1ba 72 * chance to clean up.
Rohit Grover 118:620d28e7a1ba 73 */
Rohit Grover 118:620d28e7a1ba 74 virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) {
Rohit Grover 118:620d28e7a1ba 75 if (params->charHandle == controlPoint.getValueAttribute().getHandle()) {
Rohit Grover 119:18684018b83e 76 /* At present, writing anything will do the trick--this needs to be improved. */
Rohit Grover 118:620d28e7a1ba 77 if (handoverCallback) {
Rohit Grover 118:620d28e7a1ba 78 handoverCallback();
Rohit Grover 118:620d28e7a1ba 79 }
Rohit Grover 118:620d28e7a1ba 80
Rohit Grover 118:620d28e7a1ba 81 bootloader_start();
Rohit Grover 118:620d28e7a1ba 82 }
Rohit Grover 118:620d28e7a1ba 83 }
Rohit Grover 118:620d28e7a1ba 84
Rohit Grover 118:620d28e7a1ba 85 private:
Rohit Grover 118:620d28e7a1ba 86 static const unsigned SIZEOF_CONTROL_BYTES = 2;
Rohit Grover 119:18684018b83e 87 static const unsigned SIZEOF_PACKET_BYTES = 20;
Rohit Grover 118:620d28e7a1ba 88
Rohit Grover 118:620d28e7a1ba 89 static ResetPrepare_t handoverCallback; /**< application specific handover callback. */
Rohit Grover 118:620d28e7a1ba 90
Rohit Grover 118:620d28e7a1ba 91 private:
Rohit Grover 118:620d28e7a1ba 92 BLEDevice &ble;
Rohit Grover 118:620d28e7a1ba 93 uint8_t controlBytes[SIZEOF_CONTROL_BYTES];
Rohit Grover 119:18684018b83e 94 uint8_t packetBytes[SIZEOF_PACKET_BYTES];
Rohit Grover 119:18684018b83e 95
Rohit Grover 119:18684018b83e 96 /**< Writing to the control characteristic triggers the handover to dfu-
Rohit Grover 119:18684018b83e 97 * bootloader. At present, writing anything will do the trick--this needs
Rohit Grover 119:18684018b83e 98 * to be improved. */
Rohit Grover 118:620d28e7a1ba 99 GattCharacteristic controlPoint;
Rohit Grover 119:18684018b83e 100
Rohit Grover 119:18684018b83e 101 /**< The packet characteristic in this service doesn't do anything meaningful, but
Rohit Grover 119:18684018b83e 102 * is only a placeholder to mimic the corresponding characteristic in the
Rohit Grover 119:18684018b83e 103 * actual DFU service implemented by the bootloader. Without this, some
Rohit Grover 119:18684018b83e 104 * FOTA clients might get confused as service definitions change after
Rohit Grover 119:18684018b83e 105 * handing control over to the bootloader. */
Rohit Grover 119:18684018b83e 106 GattCharacteristic packet;
Rohit Grover 118:620d28e7a1ba 107 };
Rohit Grover 118:620d28e7a1ba 108
Rohit Grover 118:620d28e7a1ba 109 #endif /* #ifndef __BLE_DFU_SERVICE_H__*/