This is a basic code to be used for Sequana BLE Lab exercises.

Committer:
lru
Date:
Fri Mar 22 10:11:59 2019 +0000
Revision:
4:44690f4495ef
Parent:
3:6f1e1510dd3e
Initialized properly device name characteristic and changed type of advertising MAC address used to guarantee uniqueness.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lru 0:ff033dfc838b 1 /* mbed Microcontroller Library
lru 0:ff033dfc838b 2 * Copyright (c) 2006-2015 ARM Limited
lru 0:ff033dfc838b 3 * Copyright (c) 2017-2019 Future Electronics
lru 0:ff033dfc838b 4 *
lru 0:ff033dfc838b 5 * Licensed under the Apache License, Version 2.0 (the "License");
lru 0:ff033dfc838b 6 * you may not use this file except in compliance with the License.
lru 0:ff033dfc838b 7 * You may obtain a copy of the License at
lru 0:ff033dfc838b 8 *
lru 0:ff033dfc838b 9 * http://www.apache.org/licenses/LICENSE-2.0
lru 0:ff033dfc838b 10 *
lru 0:ff033dfc838b 11 * Unless required by applicable law or agreed to in writing, software
lru 0:ff033dfc838b 12 * distributed under the License is distributed on an "AS IS" BASIS,
lru 0:ff033dfc838b 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
lru 0:ff033dfc838b 14 * See the License for the specific language governing permissions and
lru 0:ff033dfc838b 15 * limitations under the License.
lru 0:ff033dfc838b 16 */
lru 0:ff033dfc838b 17
lru 0:ff033dfc838b 18 #include <events/mbed_events.h>
lru 0:ff033dfc838b 19 #include <mbed.h>
lru 0:ff033dfc838b 20 #include "ble/BLE.h"
lru 0:ff033dfc838b 21 #include "pretty_printer.h"
lru 0:ff033dfc838b 22
lru 0:ff033dfc838b 23 #include <mbed.h>
lru 0:ff033dfc838b 24 #include <vector>
lru 0:ff033dfc838b 25 #include "events/mbed_events.h"
lru 0:ff033dfc838b 26 #include "ble/BLE.h"
lru 0:ff033dfc838b 27 #include "ble/gap/Gap.h"
lru 0:ff033dfc838b 28 #include "SequanaPrimaryService.h"
lru 2:06e62a299a74 29 #include "Kmx65.h"
lru 0:ff033dfc838b 30
lru 0:ff033dfc838b 31 using namespace sequana;
lru 0:ff033dfc838b 32
lru 3:6f1e1510dd3e 33 /* Advertised device name, max length is 8 characters */
lru 1:7dd41f0bd204 34 const static char DEVICE_NAME[] = "ChangeMe";
lru 0:ff033dfc838b 35
lru 0:ff033dfc838b 36 static sequana::PrimaryService *sequana_service_ptr;
lru 0:ff033dfc838b 37
lru 0:ff033dfc838b 38 static EventQueue event_queue(/* event count */ 64 * EVENTS_EVENT_SIZE);
lru 0:ff033dfc838b 39
lru 0:ff033dfc838b 40 /* Buses and I/O */
lru 0:ff033dfc838b 41 SPI spi1(SPI_MOSI, SPI_MISO, SPI_CLK);
lru 0:ff033dfc838b 42
lru 0:ff033dfc838b 43 /* Sensor declarations */
lru 2:06e62a299a74 44 Kmx65Sensor kmx65(spi1, P9_5);
lru 0:ff033dfc838b 45
lru 0:ff033dfc838b 46 class SequanaDemo : ble::Gap::EventHandler {
lru 0:ff033dfc838b 47 public:
lru 0:ff033dfc838b 48 SequanaDemo(BLE &ble, events::EventQueue &event_queue, sequana::PrimaryService& primary_service) :
lru 0:ff033dfc838b 49 _ble(ble),
lru 0:ff033dfc838b 50 _event_queue(event_queue),
lru 0:ff033dfc838b 51 _led1(LED1, 1),
lru 0:ff033dfc838b 52 _connected(false),
lru 0:ff033dfc838b 53 _primary_uuid(sequana::PrimaryService::UUID_SEQUANA_PRIMARY_SERVICE),
lru 0:ff033dfc838b 54 _primary_service(primary_service),
lru 0:ff033dfc838b 55 _adv_data_builder(_adv_buffer) { }
lru 0:ff033dfc838b 56
lru 0:ff033dfc838b 57 void start() {
lru 0:ff033dfc838b 58 _ble.gap().setEventHandler(this);
lru 0:ff033dfc838b 59
lru 0:ff033dfc838b 60 _ble.init(this, &SequanaDemo::on_init_complete);
lru 0:ff033dfc838b 61 }
lru 0:ff033dfc838b 62
lru 0:ff033dfc838b 63 private:
lru 0:ff033dfc838b 64 /** Callback triggered when the ble initialization process has finished */
lru 0:ff033dfc838b 65 void on_init_complete(BLE::InitializationCompleteCallbackContext *params) {
lru 0:ff033dfc838b 66 if (params->error != BLE_ERROR_NONE) {
lru 0:ff033dfc838b 67 printf("BLE initialization failed\n");
lru 0:ff033dfc838b 68 return;
lru 0:ff033dfc838b 69 }
lru 0:ff033dfc838b 70
lru 0:ff033dfc838b 71 print_mac_address();
lru 0:ff033dfc838b 72
lru 0:ff033dfc838b 73 _event_queue.call_every(500, this, &SequanaDemo::blink);
lru 0:ff033dfc838b 74
lru 0:ff033dfc838b 75 start_advertising();
lru 0:ff033dfc838b 76 }
lru 0:ff033dfc838b 77
lru 0:ff033dfc838b 78 void start_advertising() {
lru 4:44690f4495ef 79 _ble.gap().setDeviceName((const uint8_t *)DEVICE_NAME);
lru 4:44690f4495ef 80
lru 0:ff033dfc838b 81 /* Create advertising parameters and payload */
lru 0:ff033dfc838b 82
lru 0:ff033dfc838b 83 ble::AdvertisingParameters adv_parameters(
lru 0:ff033dfc838b 84 ble::advertising_type_t::CONNECTABLE_UNDIRECTED,
lru 0:ff033dfc838b 85 ble::adv_interval_t(ble::millisecond_t(1000))
lru 0:ff033dfc838b 86 );
lru 4:44690f4495ef 87 adv_parameters.setOwnAddressType(ble::own_address_type_t::RESOLVABLE_PRIVATE_ADDRESS_PUBLIC_FALLBACK);
lru 0:ff033dfc838b 88
lru 0:ff033dfc838b 89 _adv_data_builder.setFlags();
lru 0:ff033dfc838b 90 _adv_data_builder.setLocalServiceList(mbed::make_Span(&_primary_uuid, 1));
lru 0:ff033dfc838b 91 _adv_data_builder.setName(DEVICE_NAME);
lru 0:ff033dfc838b 92
lru 0:ff033dfc838b 93 /* Setup advertising */
lru 0:ff033dfc838b 94
lru 0:ff033dfc838b 95 ble_error_t error = _ble.gap().setAdvertisingParameters(
lru 0:ff033dfc838b 96 ble::LEGACY_ADVERTISING_HANDLE,
lru 0:ff033dfc838b 97 adv_parameters
lru 0:ff033dfc838b 98 );
lru 0:ff033dfc838b 99
lru 0:ff033dfc838b 100 if (error) {
lru 0:ff033dfc838b 101 printf("_ble.gap().setAdvertisingParameters() failed\n");
lru 0:ff033dfc838b 102 return;
lru 0:ff033dfc838b 103 }
lru 0:ff033dfc838b 104
lru 0:ff033dfc838b 105 error = _ble.gap().setAdvertisingPayload(
lru 0:ff033dfc838b 106 ble::LEGACY_ADVERTISING_HANDLE,
lru 0:ff033dfc838b 107 _adv_data_builder.getAdvertisingData()
lru 0:ff033dfc838b 108 );
lru 0:ff033dfc838b 109
lru 0:ff033dfc838b 110 if (error) {
lru 0:ff033dfc838b 111 printf("_ble.gap().setAdvertisingPayload() failed\n");
lru 0:ff033dfc838b 112 return;
lru 0:ff033dfc838b 113 }
lru 0:ff033dfc838b 114
lru 0:ff033dfc838b 115 /* Start advertising */
lru 0:ff033dfc838b 116
lru 0:ff033dfc838b 117 error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
lru 0:ff033dfc838b 118
lru 0:ff033dfc838b 119 if (error) {
lru 0:ff033dfc838b 120 printf("_ble.gap().startAdvertising() failed\n");
lru 0:ff033dfc838b 121 return;
lru 0:ff033dfc838b 122 }
lru 0:ff033dfc838b 123 }
lru 0:ff033dfc838b 124
lru 0:ff033dfc838b 125 void blink(void) {
lru 0:ff033dfc838b 126 /* LED will be on when a client is connected or will blink while advertising */
lru 0:ff033dfc838b 127 if (_connected) {
lru 0:ff033dfc838b 128 _led1 = 1;
lru 0:ff033dfc838b 129 } else {
lru 0:ff033dfc838b 130 _led1 = !_led1;
lru 0:ff033dfc838b 131 }
lru 0:ff033dfc838b 132 }
lru 0:ff033dfc838b 133
lru 0:ff033dfc838b 134 private:
lru 0:ff033dfc838b 135 /* Event handler */
lru 0:ff033dfc838b 136
lru 0:ff033dfc838b 137 void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) {
lru 0:ff033dfc838b 138 _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
lru 0:ff033dfc838b 139 _connected = false;
lru 0:ff033dfc838b 140 }
lru 0:ff033dfc838b 141
lru 0:ff033dfc838b 142 virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) {
lru 0:ff033dfc838b 143 if (event.getStatus() == BLE_ERROR_NONE) {
lru 0:ff033dfc838b 144 _connected = true;
lru 0:ff033dfc838b 145 }
lru 0:ff033dfc838b 146 }
lru 0:ff033dfc838b 147
lru 0:ff033dfc838b 148 private:
lru 0:ff033dfc838b 149 BLE &_ble;
lru 0:ff033dfc838b 150 events::EventQueue &_event_queue;
lru 0:ff033dfc838b 151 DigitalOut _led1;
lru 0:ff033dfc838b 152 bool _connected;
lru 0:ff033dfc838b 153 UUID _primary_uuid;
lru 0:ff033dfc838b 154 sequana::PrimaryService &_primary_service;
lru 0:ff033dfc838b 155 uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
lru 0:ff033dfc838b 156 ble::AdvertisingDataBuilder _adv_data_builder;
lru 0:ff033dfc838b 157 };
lru 0:ff033dfc838b 158
lru 0:ff033dfc838b 159
lru 0:ff033dfc838b 160 /** Schedule processing of events from the BLE middleware in the event queue. */
lru 0:ff033dfc838b 161 void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) {
lru 0:ff033dfc838b 162 event_queue.call(Callback<void()>(&context->ble, &BLE::processEvents));
lru 0:ff033dfc838b 163 }
lru 0:ff033dfc838b 164
lru 0:ff033dfc838b 165 int main()
lru 0:ff033dfc838b 166 {
lru 0:ff033dfc838b 167 printf("Application processor started.\n\n");
lru 0:ff033dfc838b 168
lru 0:ff033dfc838b 169 /* Initialize bus(es) (placeholder) */
lru 2:06e62a299a74 170 spi1.format(8, 0);
lru 0:ff033dfc838b 171 spi1.frequency(1000000);
lru 0:ff033dfc838b 172
lru 0:ff033dfc838b 173 /* Setup BLE interface */
lru 0:ff033dfc838b 174 BLE &ble = BLE::Instance();
lru 0:ff033dfc838b 175 ble.onEventsToProcess(schedule_ble_events);
lru 0:ff033dfc838b 176
lru 0:ff033dfc838b 177 /* Setup primary service (placeholder). */
lru 2:06e62a299a74 178 sequana_service_ptr = new sequana::PrimaryService(ble, kmx65);
lru 0:ff033dfc838b 179
lru 0:ff033dfc838b 180 /* Start BLE / demo application */
lru 0:ff033dfc838b 181 SequanaDemo demo(ble, event_queue, *sequana_service_ptr);
lru 0:ff033dfc838b 182 demo.start();
lru 0:ff033dfc838b 183
lru 0:ff033dfc838b 184 printf("BLE started (%s).\n\n", DEVICE_NAME);
lru 0:ff033dfc838b 185
lru 2:06e62a299a74 186 /* Start all sensors */
lru 2:06e62a299a74 187 kmx65.start(event_queue);
lru 2:06e62a299a74 188
lru 0:ff033dfc838b 189 /* Process all events */
lru 0:ff033dfc838b 190 event_queue.dispatch_forever();
lru 0:ff033dfc838b 191
lru 0:ff033dfc838b 192 return 0;
lru 0:ff033dfc838b 193 }
lru 0:ff033dfc838b 194