mbed.org local branch of microbit-dal. The real version lives in git at https://github.com/lancaster-university/microbit-dal

Dependencies:   BLE_API nRF51822 mbed-dev-bin

Dependents:   microbit Microbit IoTChallenge1 microbit ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicroBitDFUService.cpp Source File

MicroBitDFUService.cpp

00001 /*
00002 The MIT License (MIT)
00003 
00004 Copyright (c) 2016 British Broadcasting Corporation.
00005 This software is provided by Lancaster University by arrangement with the BBC.
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a
00008 copy of this software and associated documentation files (the "Software"),
00009 to deal in the Software without restriction, including without limitation
00010 the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011 and/or sell copies of the Software, and to permit persons to whom the
00012 Software is furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00023 DEALINGS IN THE SOFTWARE.
00024 */
00025 
00026 /**
00027  * Class definition for a MicroBit Device Firmware Update loader.
00028  *
00029  * This is actually just a frontend to a memory resident nordic DFU loader.
00030  *
00031  * We rely on the BLE standard pairing processes to provide encryption and authentication.
00032  * We assume any device that is paied with the micro:bit is authorized to reprogram the device.
00033  *
00034  */
00035 #include "MicroBitConfig.h"
00036 #include "MicroBitDFUService.h"
00037 #include "ble/UUID.h"
00038 #include "MicroBitConfig.h"
00039 
00040 #if !defined(__arm)
00041 #pragma GCC diagnostic ignored "-Wunused-function"
00042 #pragma GCC diagnostic push
00043 #pragma GCC diagnostic ignored "-Wunused-parameter"
00044 #endif
00045 
00046 /*
00047  * The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ
00048  * If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL)
00049  * The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this
00050  * as a compatability option, but does not support the options used...
00051  */
00052 extern "C" {
00053 #include "dfu_app_handler.h"
00054 }
00055 
00056 /*
00057  * Return to our predefined compiler settings.
00058  */
00059 #if !defined(__arm)
00060 #pragma GCC diagnostic pop
00061 #endif
00062 
00063 
00064 /**
00065   * Constructor.
00066   * Initialise the Device Firmware Update service.
00067   * @param _ble The instance of a BLE device that we're running on.
00068   */
00069 MicroBitDFUService::MicroBitDFUService(BLEDevice &_ble) :
00070     ble(_ble)
00071 {
00072     // Opcodes can be issued here to control the MicroBitDFU Service, as defined above.
00073     GattCharacteristic  microBitDFUServiceControlCharacteristic(MicroBitDFUServiceControlCharacteristicUUID, &controlByte, 0, sizeof(uint8_t),
00074             GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
00075 
00076     controlByte = 0x00;
00077 
00078     // Set default security requirements
00079     microBitDFUServiceControlCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
00080 
00081     GattCharacteristic *characteristics[] = {&microBitDFUServiceControlCharacteristic};
00082     GattService         service(MicroBitDFUServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
00083 
00084     ble.addService(service);
00085 
00086     microBitDFUServiceControlCharacteristicHandle = microBitDFUServiceControlCharacteristic.getValueHandle();
00087 
00088     ble.gattServer().write(microBitDFUServiceControlCharacteristicHandle, &controlByte, sizeof(uint8_t));
00089     ble.gattServer().onDataWritten(this, &MicroBitDFUService::onDataWritten);
00090 }
00091 
00092 /**
00093   * Callback. Invoked when any of our attributes are written via BLE.
00094   */
00095 void MicroBitDFUService::onDataWritten(const GattWriteCallbackParams *params)
00096 {
00097     if (params->handle == microBitDFUServiceControlCharacteristicHandle)
00098     {
00099         if(params->len > 0 && params->data[0] == MICROBIT_DFU_OPCODE_START_DFU)
00100         {
00101             // TODO: Raise a SYSTEM event here.
00102             //uBit.display.stopAnimation();
00103             //uBit.display.clear();
00104 
00105 #if CONFIG_ENABLED(MICROBIT_DBG)
00106             printf("  ACTIVATING BOOTLOADER.\n");
00107 #endif
00108 
00109             // Perform an explicit disconnection to assist our peer to reconnect to the DFU service
00110             ble.disconnect(Gap::REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF);
00111 
00112             wait_ms(1000);
00113 
00114             // Call bootloader_start implicitly trough a event handler call
00115             // it is a work around for bootloader_start not being public in sdk 8.1
00116             ble_dfu_t p_dfu;
00117             ble_dfu_evt_t p_evt;
00118 
00119             p_dfu.conn_handle = params->connHandle;
00120             p_evt.ble_dfu_evt_type = BLE_DFU_START;
00121 
00122             dfu_app_on_dfu_evt(&p_dfu, &p_evt);
00123         }
00124     }
00125 }
00126 
00127 
00128 /**
00129   * UUID definitions for BLE Services and Characteristics.
00130   */
00131 const uint8_t              MicroBitDFUServiceUUID[] = {
00132     0xe9,0x5d,0x93,0xb0,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00133 };
00134 
00135 const uint8_t              MicroBitDFUServiceControlCharacteristicUUID[] = {
00136     0xe9,0x5d,0x93,0xb1,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00137 };