Bluetooth Low Energy enabled device with "Switch" feature, compatible with BlueST Protocol.

Bluetooth Low Energy enabled device with "Switch" feature, compatible with BlueST Protocol.

Committer:
Davidroid
Date:
Thu May 31 18:30:29 2018 +0000
Revision:
4:67ff1ddd11e2
Parent:
3:b880b9a9ccdf
Child:
5:1651815d2a74
Send switch_state rather than toggle_state via BLE

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Davidroid 0:6b34c49b5285 1 /**
Davidroid 0:6b34c49b5285 2 *******************************************************************************
Davidroid 0:6b34c49b5285 3 * @file main.cpp
Davidroid 0:6b34c49b5285 4 * @author Davide Aliprandi, STMicroelectronics
Davidroid 0:6b34c49b5285 5 * @version V1.0.0
Davidroid 0:6b34c49b5285 6 * @date March 31st, 2018
Davidroid 0:6b34c49b5285 7 * @brief mbed test application for the STMicroelectronics X-NUCLEO-IDB05A1
Davidroid 0:6b34c49b5285 8 * Bluetooth Low energy Expansion Board.
Davidroid 0:6b34c49b5285 9 *******************************************************************************
Davidroid 0:6b34c49b5285 10 * @attention
Davidroid 0:6b34c49b5285 11 *
Davidroid 0:6b34c49b5285 12 * <h2><center>&copy; COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
Davidroid 0:6b34c49b5285 13 *
Davidroid 0:6b34c49b5285 14 * Redistribution and use in source and binary forms, with or without
Davidroid 0:6b34c49b5285 15 * modification, are permitted provided that the following conditions are met:
Davidroid 0:6b34c49b5285 16 * 1. Redistributions of source code must retain the above copyright notice,
Davidroid 0:6b34c49b5285 17 * this list of conditions and the following disclaimer.
Davidroid 0:6b34c49b5285 18 * 2. Redistributions in binary form must reproduce the above copyright
Davidroid 0:6b34c49b5285 19 * notice, this list of conditions and the following disclaimer in the
Davidroid 0:6b34c49b5285 20 * documentation and/or other materials provided with the distribution.
Davidroid 0:6b34c49b5285 21 * 3. Neither the name of STMicroelectronics nor the names of its
Davidroid 0:6b34c49b5285 22 * contributors may be used to endorse or promote products derived from
Davidroid 0:6b34c49b5285 23 * this software without specific prior written permission.
Davidroid 0:6b34c49b5285 24 *
Davidroid 0:6b34c49b5285 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Davidroid 0:6b34c49b5285 26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Davidroid 0:6b34c49b5285 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Davidroid 0:6b34c49b5285 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
Davidroid 0:6b34c49b5285 29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Davidroid 0:6b34c49b5285 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Davidroid 0:6b34c49b5285 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Davidroid 0:6b34c49b5285 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Davidroid 0:6b34c49b5285 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Davidroid 0:6b34c49b5285 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Davidroid 0:6b34c49b5285 35 * POSSIBILITY OF SUCH DAMAGE.
Davidroid 0:6b34c49b5285 36 *
Davidroid 0:6b34c49b5285 37 *******************************************************************************
Davidroid 0:6b34c49b5285 38 */
Davidroid 0:6b34c49b5285 39
Davidroid 0:6b34c49b5285 40
Davidroid 0:6b34c49b5285 41 /* Includes ------------------------------------------------------------------*/
Davidroid 0:6b34c49b5285 42
Davidroid 0:6b34c49b5285 43 /* mbed specific header files. */
Davidroid 0:6b34c49b5285 44 #include <events/mbed_events.h>
Davidroid 0:6b34c49b5285 45 #include <mbed.h>
Davidroid 0:6b34c49b5285 46 #include "ble/BLE.h"
Davidroid 0:6b34c49b5285 47 #include "CustomService.h"
Davidroid 0:6b34c49b5285 48
Davidroid 0:6b34c49b5285 49
Davidroid 0:6b34c49b5285 50 /* Definitions ---------------------------------------------------------------*/
Davidroid 0:6b34c49b5285 51
Davidroid 0:6b34c49b5285 52 #define BLE_ADVERTISING_INTERVAL_ms 1000
Davidroid 0:6b34c49b5285 53 #define BLUETOOTH_PERIODIC_CALLBACK_ms 500
Davidroid 0:6b34c49b5285 54 #define DELAY_1 100
Davidroid 0:6b34c49b5285 55
Davidroid 0:6b34c49b5285 56
Davidroid 0:6b34c49b5285 57 /* Variables -----------------------------------------------------------------*/
Davidroid 0:6b34c49b5285 58
Davidroid 4:67ff1ddd11e2 59 /* Switch and toggle state. */
Davidroid 4:67ff1ddd11e2 60 CustomService::switch_state_t switch_state;
Davidroid 0:6b34c49b5285 61 bool toggle_state;
Davidroid 0:6b34c49b5285 62
Davidroid 0:6b34c49b5285 63 /* LED to indicate system state. */
Davidroid 0:6b34c49b5285 64 DigitalOut led_state(LED1); //Conflicts with SPI CLK on D13.
Davidroid 0:6b34c49b5285 65
Davidroid 0:6b34c49b5285 66 /* Bluetooth. */
Davidroid 1:bb6dbece87c1 67 const static char DEVICE_NAME[] = "SWITCH_DEVICE";
Davidroid 0:6b34c49b5285 68 const static uint8_t MANUFACTURER_SPECIFIC_DATA[]= {0x01,0x80,0x20,0x00,0x00,0x00};
Davidroid 0:6b34c49b5285 69 static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE);
Davidroid 0:6b34c49b5285 70 CustomService *custom_service;
Davidroid 0:6b34c49b5285 71
Davidroid 0:6b34c49b5285 72 /* Button event. */
Davidroid 0:6b34c49b5285 73 InterruptIn event(USER_BUTTON);
Davidroid 0:6b34c49b5285 74
Davidroid 0:6b34c49b5285 75
Davidroid 0:6b34c49b5285 76 /* Bluetooth related functions -----------------------------------------------*/
Davidroid 0:6b34c49b5285 77
Davidroid 0:6b34c49b5285 78 void on_disconnection_callback(const Gap::DisconnectionCallbackParams_t *params)
Davidroid 0:6b34c49b5285 79 {
Davidroid 0:6b34c49b5285 80 (void) params;
Davidroid 0:6b34c49b5285 81 BLE::Instance().gap().startAdvertising();
Davidroid 0:6b34c49b5285 82 }
Davidroid 0:6b34c49b5285 83
Davidroid 0:6b34c49b5285 84 /**
Davidroid 0:6b34c49b5285 85 * This callback allows the custom service to read updates from the
Davidroid 0:6b34c49b5285 86 * characteristic.
Davidroid 0:6b34c49b5285 87 *
Davidroid 0:6b34c49b5285 88 * @param[in] params
Davidroid 0:6b34c49b5285 89 * Information about the characterisitc being updated.
Davidroid 0:6b34c49b5285 90 */
Davidroid 0:6b34c49b5285 91 void on_data_read_callback(const GattReadCallbackParams *params) {
Davidroid 0:6b34c49b5285 92 static uint16_t time_stamp = 0;
Davidroid 0:6b34c49b5285 93
Davidroid 0:6b34c49b5285 94 if (params->handle == custom_service->getValueHandle()) {
Davidroid 0:6b34c49b5285 95 // Reading led state and sending it via bluetooth.
Davidroid 0:6b34c49b5285 96 if (BLE::Instance().getGapState().connected) {
Davidroid 4:67ff1ddd11e2 97 switch_state = led_state.read() ? CustomService::SWITCH_ON : CustomService::SWITCH_OFF;
Davidroid 4:67ff1ddd11e2 98 event_queue.call(Callback<void(uint16_t, uint8_t)>(custom_service, &CustomService::send_state), time_stamp++, switch_state);
Davidroid 0:6b34c49b5285 99 }
Davidroid 0:6b34c49b5285 100 }
Davidroid 0:6b34c49b5285 101 }
Davidroid 0:6b34c49b5285 102
Davidroid 0:6b34c49b5285 103 /**
Davidroid 0:6b34c49b5285 104 * This callback allows the custom service to write updates to the
Davidroid 0:6b34c49b5285 105 * characteristic.
Davidroid 0:6b34c49b5285 106 *
Davidroid 0:6b34c49b5285 107 * @param[in] params
Davidroid 0:6b34c49b5285 108 * Information about the characterisitc being updated.
Davidroid 0:6b34c49b5285 109 */
Davidroid 0:6b34c49b5285 110 void on_data_written_callback(const GattWriteCallbackParams *params) {
Davidroid 0:6b34c49b5285 111
Davidroid 0:6b34c49b5285 112 if (params->handle == custom_service->getValueHandle()) {
Davidroid 0:6b34c49b5285 113 /* Receiving command via bluetooth and writing it to the led state. */
Davidroid 4:67ff1ddd11e2 114 led_state.write(((CustomService::switch_state_t) ((uint8_t *) (params->data))[SWITCH_DATA_INDEX]));
Davidroid 0:6b34c49b5285 115 }
Davidroid 0:6b34c49b5285 116 }
Davidroid 0:6b34c49b5285 117
Davidroid 0:6b34c49b5285 118 /**
Davidroid 0:6b34c49b5285 119 * This function is called periodically.
Davidroid 0:6b34c49b5285 120 */
Davidroid 0:6b34c49b5285 121 void periodic_callback(void)
Davidroid 0:6b34c49b5285 122 {
Davidroid 0:6b34c49b5285 123 static uint16_t time_stamp = 0;
Davidroid 0:6b34c49b5285 124
Davidroid 0:6b34c49b5285 125 /* Reading toggle command and sending it via bluetooth. */
Davidroid 0:6b34c49b5285 126 if (toggle_state) {
Davidroid 0:6b34c49b5285 127 if (BLE::Instance().getGapState().connected) {
Davidroid 4:67ff1ddd11e2 128 event_queue.call(Callback<void(uint16_t, uint8_t)>(custom_service, &CustomService::send_state), time_stamp++, switch_state);
Davidroid 0:6b34c49b5285 129 toggle_state = false;
Davidroid 0:6b34c49b5285 130 }
Davidroid 0:6b34c49b5285 131 }
Davidroid 0:6b34c49b5285 132 }
Davidroid 0:6b34c49b5285 133
Davidroid 0:6b34c49b5285 134 /**
Davidroid 0:6b34c49b5285 135 * This function is called when the ble initialization process has failled.
Davidroid 0:6b34c49b5285 136 */
Davidroid 0:6b34c49b5285 137 void on_ble_init_error_callback(BLE &ble, ble_error_t error)
Davidroid 0:6b34c49b5285 138 {
Davidroid 0:6b34c49b5285 139 /* Initialization error handling should go here */
Davidroid 0:6b34c49b5285 140 }
Davidroid 0:6b34c49b5285 141
Davidroid 0:6b34c49b5285 142 /**
Davidroid 0:6b34c49b5285 143 * Callback triggered when the ble initialization process has finished.
Davidroid 0:6b34c49b5285 144 */
Davidroid 0:6b34c49b5285 145 void ble_init_complete(BLE::InitializationCompleteCallbackContext *params)
Davidroid 0:6b34c49b5285 146 {
Davidroid 0:6b34c49b5285 147 BLE& ble = params->ble;
Davidroid 0:6b34c49b5285 148 ble_error_t error = params->error;
Davidroid 0:6b34c49b5285 149
Davidroid 0:6b34c49b5285 150 if (error != BLE_ERROR_NONE) {
Davidroid 0:6b34c49b5285 151 /* In case of error, forward the error handling to on_ble_init_error_callback */
Davidroid 0:6b34c49b5285 152 on_ble_init_error_callback(ble, error);
Davidroid 0:6b34c49b5285 153 return;
Davidroid 0:6b34c49b5285 154 }
Davidroid 0:6b34c49b5285 155
Davidroid 0:6b34c49b5285 156 /* Ensure that it is the default instance of BLE */
Davidroid 0:6b34c49b5285 157 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
Davidroid 0:6b34c49b5285 158 return;
Davidroid 0:6b34c49b5285 159 }
Davidroid 0:6b34c49b5285 160
Davidroid 0:6b34c49b5285 161 ble.gap().onDisconnection(on_disconnection_callback);
Davidroid 0:6b34c49b5285 162 ble.gattServer().onDataWritten(on_data_written_callback);
Davidroid 0:6b34c49b5285 163 //ble.gattServer().onDataRead(on_data_read_callback);
Davidroid 0:6b34c49b5285 164
Davidroid 0:6b34c49b5285 165 custom_service = new CustomService(ble);
Davidroid 0:6b34c49b5285 166
Davidroid 0:6b34c49b5285 167 /* Setup advertising data. */
Davidroid 0:6b34c49b5285 168 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
Davidroid 0:6b34c49b5285 169 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (uint8_t *) CUSTOM_SWITCH_SERVICE_UUID, sizeof(CUSTOM_SWITCH_SERVICE_UUID));
Davidroid 0:6b34c49b5285 170 ble.gap().accumulateScanResponse(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, MANUFACTURER_SPECIFIC_DATA, sizeof(MANUFACTURER_SPECIFIC_DATA));
Davidroid 3:b880b9a9ccdf 171 ble.gap().accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, (const uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME) - 1);
Davidroid 0:6b34c49b5285 172 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
Davidroid 0:6b34c49b5285 173 ble.gap().setAdvertisingInterval(BLE_ADVERTISING_INTERVAL_ms);
Davidroid 0:6b34c49b5285 174 ble.gap().startAdvertising();
Davidroid 0:6b34c49b5285 175 }
Davidroid 0:6b34c49b5285 176
Davidroid 0:6b34c49b5285 177 void schedule_ble_events_processing(BLE::OnEventsToProcessCallbackContext* context) {
Davidroid 0:6b34c49b5285 178 BLE &ble = BLE::Instance();
Davidroid 0:6b34c49b5285 179 event_queue.call(Callback<void()>(&ble, &BLE::processEvents));
Davidroid 0:6b34c49b5285 180 }
Davidroid 0:6b34c49b5285 181
Davidroid 0:6b34c49b5285 182
Davidroid 0:6b34c49b5285 183 /* Custom service related functions ------------------------------------------*/
Davidroid 0:6b34c49b5285 184
Davidroid 0:6b34c49b5285 185 void button_callback(void) {
Davidroid 4:67ff1ddd11e2 186 switch_state = (CustomService::switch_state_t) (CustomService::SWITCH_ON - switch_state);
Davidroid 0:6b34c49b5285 187 toggle_state = true;
Davidroid 0:6b34c49b5285 188 }
Davidroid 0:6b34c49b5285 189
Davidroid 0:6b34c49b5285 190
Davidroid 0:6b34c49b5285 191 /* Main function -------------------------------------------------------------*/
Davidroid 0:6b34c49b5285 192
Davidroid 0:6b34c49b5285 193 int main()
Davidroid 0:6b34c49b5285 194 {
Davidroid 0:6b34c49b5285 195 /*----- Initialization. -----*/
Davidroid 0:6b34c49b5285 196
Davidroid 0:6b34c49b5285 197 /* Printing to the console. */
Davidroid 0:6b34c49b5285 198 printf("Switch Node Application Example\r\n\n");
Davidroid 0:6b34c49b5285 199
Davidroid 0:6b34c49b5285 200 /* Bluetooth. */
Davidroid 0:6b34c49b5285 201 event_queue.call_every(BLUETOOTH_PERIODIC_CALLBACK_ms, periodic_callback);
Davidroid 0:6b34c49b5285 202 BLE &ble = BLE::Instance();
Davidroid 0:6b34c49b5285 203 ble.onEventsToProcess(schedule_ble_events_processing);
Davidroid 0:6b34c49b5285 204 ble.init(ble_init_complete);
Davidroid 0:6b34c49b5285 205
Davidroid 0:6b34c49b5285 206 /* Attaching and enabling interrupt handlers. */
Davidroid 0:6b34c49b5285 207 event.fall(button_callback);
Davidroid 0:6b34c49b5285 208
Davidroid 4:67ff1ddd11e2 209 /* Setting up initial state: switch feature OFF, i.e. led OFF, and no toggle
Davidroid 4:67ff1ddd11e2 210 state triggered. */
Davidroid 4:67ff1ddd11e2 211 switch_state = CustomService::SWITCH_OFF;
Davidroid 4:67ff1ddd11e2 212 led_state.write(switch_state);
Davidroid 0:6b34c49b5285 213 toggle_state = false;
Davidroid 0:6b34c49b5285 214
Davidroid 0:6b34c49b5285 215 /* Start. */
Davidroid 0:6b34c49b5285 216 event_queue.dispatch_forever();
Davidroid 0:6b34c49b5285 217
Davidroid 0:6b34c49b5285 218 return 0;
Davidroid 0:6b34c49b5285 219 }