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

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.