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

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

Revision:
0:6b34c49b5285
Child:
1:bb6dbece87c1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/main.cpp	Tue Apr 17 15:13:04 2018 +0000
@@ -0,0 +1,231 @@
+/**
+ *******************************************************************************
+ * @file    main.cpp
+ * @author  Davide Aliprandi, STMicroelectronics
+ * @version V1.0.0
+ * @date    March 31st, 2018
+ * @brief   mbed test application for the STMicroelectronics X-NUCLEO-IDB05A1
+ *          Bluetooth Low energy Expansion Board.
+ *******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its
+ *      contributors may be used to endorse or promote products derived from
+ *      this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+
+/* mbed specific header files. */
+#include <events/mbed_events.h>
+#include <mbed.h>
+#include "ble/BLE.h"
+#include "CustomService.h"
+
+/* Helper header files. */
+#include "DevSPI.h"
+
+/* Component specific header files. */
+#include "L6474.h"
+
+
+/* Definitions ---------------------------------------------------------------*/
+
+#define BLE_ADVERTISING_INTERVAL_ms 1000
+#define BLUETOOTH_PERIODIC_CALLBACK_ms 500
+#define DELAY_1 100
+
+
+/* Types ---------------------------------------------------------------------*/
+
+/* Toggle state. */
+typedef enum
+{
+    TOGGLE_OFF = 0,
+    TOGGLE_ON
+} toggle_t;
+
+
+/* Variables -----------------------------------------------------------------*/
+
+/* Button state. */
+bool toggle_state;
+
+/* LED to indicate system state. */
+DigitalOut led_state(LED1); //Conflicts with SPI CLK on D13.
+
+/* Bluetooth. */
+const static char    DEVICE_NAME[] = "SWITCH_DEVICE_2";
+const static uint8_t MANUFACTURER_SPECIFIC_DATA[]= {0x01,0x80,0x20,0x00,0x00,0x00};
+static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE);
+CustomService *custom_service;
+
+/* Button event. */
+InterruptIn event(USER_BUTTON);
+
+
+/* Bluetooth related functions -----------------------------------------------*/
+
+void on_disconnection_callback(const Gap::DisconnectionCallbackParams_t *params)
+{
+    (void) params;
+    BLE::Instance().gap().startAdvertising();
+}
+
+/**
+ * This callback allows the custom service to read updates from the
+ * characteristic.
+ *
+ * @param[in] params
+ *     Information about the characterisitc being updated.
+ */
+void on_data_read_callback(const GattReadCallbackParams *params) {
+    static uint16_t time_stamp = 0;
+
+    if (params->handle == custom_service->getValueHandle()) {
+        // Reading led state and sending it via bluetooth.
+        if (BLE::Instance().getGapState().connected) {
+            //event_queue.call(Callback<void(uint16_t, uint8_t)>(custom_service, &CustomService::send_state), time_stamp++, led_state.read() ? CustomService::SWITCH_ON : CustomService::SWITCH_OFF);
+            event_queue.call(Callback<void(uint16_t, uint8_t)>(custom_service, &CustomService::send_state), time_stamp++, TOGGLE_OFF);  // To clean the BLE buffer.
+        }
+    }
+}
+
+/**
+ * This callback allows the custom service to write updates to the
+ * characteristic.
+ *
+ * @param[in] params
+ *     Information about the characterisitc being updated.
+ */
+void on_data_written_callback(const GattWriteCallbackParams *params) {
+
+    if (params->handle == custom_service->getValueHandle()) {
+        /* Receiving command via bluetooth and writing it to the led state. */
+        led_state.write(((CustomService::switch_state_t) ((uint8_t *) (params->data))[0]));
+    }
+}
+
+/**
+ * This function is called periodically.
+ */
+void periodic_callback(void)
+{
+    static uint16_t time_stamp = 0;
+
+    /* Reading toggle command and sending it via bluetooth. */
+    if (toggle_state) {
+        if (BLE::Instance().getGapState().connected) {
+            event_queue.call(Callback<void(uint16_t, uint8_t)>(custom_service, &CustomService::send_state), time_stamp++, toggle_state ? TOGGLE_ON : TOGGLE_OFF);
+            toggle_state = false;
+        }
+    }
+}
+
+/**
+ * This function is called when the ble initialization process has failled.
+ */
+void on_ble_init_error_callback(BLE &ble, ble_error_t error)
+{
+    /* Initialization error handling should go here */
+}
+
+/**
+ * Callback triggered when the ble initialization process has finished.
+ */
+void ble_init_complete(BLE::InitializationCompleteCallbackContext *params)
+{
+    BLE& ble   = params->ble;
+    ble_error_t error = params->error;
+
+    if (error != BLE_ERROR_NONE) {
+        /* In case of error, forward the error handling to on_ble_init_error_callback */
+        on_ble_init_error_callback(ble, error);
+        return;
+    }
+
+    /* Ensure that it is the default instance of BLE */
+    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+        return;
+    }
+
+    ble.gap().onDisconnection(on_disconnection_callback);
+    ble.gattServer().onDataWritten(on_data_written_callback);
+    //ble.gattServer().onDataRead(on_data_read_callback);
+
+    custom_service = new CustomService(ble);
+
+    /* Setup advertising data. */
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (uint8_t *) CUSTOM_SWITCH_SERVICE_UUID, sizeof(CUSTOM_SWITCH_SERVICE_UUID));
+    ble.gap().accumulateScanResponse(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, MANUFACTURER_SPECIFIC_DATA, sizeof(MANUFACTURER_SPECIFIC_DATA));
+    ble.gap().accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, (const uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME));
+    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.gap().setAdvertisingInterval(BLE_ADVERTISING_INTERVAL_ms);
+    ble.gap().startAdvertising();
+}
+
+void schedule_ble_events_processing(BLE::OnEventsToProcessCallbackContext* context) {
+    BLE &ble = BLE::Instance();
+    event_queue.call(Callback<void()>(&ble, &BLE::processEvents));
+}
+
+
+/* Custom service related functions ------------------------------------------*/
+
+void button_callback(void) {
+    toggle_state = true;
+}
+
+
+/* Main function -------------------------------------------------------------*/
+
+int main()
+{
+    /*----- Initialization. -----*/
+
+    /* Printing to the console. */
+    printf("Switch Node Application Example\r\n\n");
+
+    /* Bluetooth. */
+    event_queue.call_every(BLUETOOTH_PERIODIC_CALLBACK_ms, periodic_callback);
+    BLE &ble = BLE::Instance();
+    ble.onEventsToProcess(schedule_ble_events_processing);
+    ble.init(ble_init_complete);
+
+    /* Attaching and enabling interrupt handlers. */
+    event.fall(button_callback);
+
+    /* Setting up initial state: led OFF, no toggle state. */
+    led_state.write(CustomService::SWITCH_OFF);
+    toggle_state = false;
+
+    /* Start. */
+    event_queue.dispatch_forever();
+
+    return 0;
+}