This library includes use cases which can be used for replicating BLE use caes.
MultipleServices.cpp@1:857e59bbf707, 2014-09-25 (annotated)
- Committer:
- hemddabral
- Date:
- Thu Sep 25 08:18:37 2014 +0000
- Revision:
- 1:857e59bbf707
- Parent:
- 0:935006092f33
- Child:
- 2:c6894656d2f1
Implemented multiple service use case involving battery, blood pressure, and heart rate service.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hemddabral | 0:935006092f33 | 1 | #include "UseCases.h" |
hemddabral | 0:935006092f33 | 2 | |
hemddabral | 0:935006092f33 | 3 | #include "mbed.h" |
hemddabral | 0:935006092f33 | 4 | |
hemddabral | 0:935006092f33 | 5 | DigitalOut myled(LED1); |
hemddabral | 0:935006092f33 | 6 | |
hemddabral | 0:935006092f33 | 7 | #include "debug.h" |
hemddabral | 0:935006092f33 | 8 | #include "btle.h" |
hemddabral | 0:935006092f33 | 9 | #include "BLEDevice.h" |
hemddabral | 0:935006092f33 | 10 | #include "UUID.h" |
hemddabral | 0:935006092f33 | 11 | #include "Utils.h" |
hemddabral | 0:935006092f33 | 12 | |
hemddabral | 0:935006092f33 | 13 | BLEDevice dev; |
hemddabral | 0:935006092f33 | 14 | |
hemddabral | 0:935006092f33 | 15 | const static char DEVICE_NAME[] = "HEALTH_DEVICE"; |
hemddabral | 0:935006092f33 | 16 | //const uint8_t device_address[6] = { 0x12, 0x34, 0x00, 0xe1, 0x80, 0x02 }; //Peripheral address |
hemddabral | 0:935006092f33 | 17 | |
hemddabral | 0:935006092f33 | 18 | void Append128bitUUID(uint8_t *uuid128_list, const LongUUID_t HRM_SERVICE_UUID_128); |
hemddabral | 0:935006092f33 | 19 | void print_array(uint8_t *array); |
hemddabral | 0:935006092f33 | 20 | |
hemddabral | 0:935006092f33 | 21 | #define MAX_SERVICES_NOS 1 |
hemddabral | 0:935006092f33 | 22 | //typedef uint8_t UUID_128_BIT[16]; |
hemddabral | 0:935006092f33 | 23 | const LongUUID_t HEART_RATE_CHAR_UUID_128 = {0x42,0x82,0x1a,0x40, 0xe4,0x77, 0x11,0xe2, 0x82,0xd0, 0x00,0x02,0xa5,0xd5,0xc5,0x1a}; |
hemddabral | 0:935006092f33 | 24 | const LongUUID_t HRM_SERVICE_UUID_128 = {0x42,0x82,0x1a,0x40, 0xe4,0x77, 0x11,0xe2, 0x82,0xd0, 0x00,0x02,0xa5,0xd5,0xc5,0x1b}; |
hemddabral | 0:935006092f33 | 25 | |
hemddabral | 0:935006092f33 | 26 | uint8_t UUID_Count=0; |
hemddabral | 0:935006092f33 | 27 | |
hemddabral | 0:935006092f33 | 28 | static uint8_t hrmCounter = 100; |
hemddabral | 0:935006092f33 | 29 | static uint8_t bpm[2] = {0x00, hrmCounter}; |
hemddabral | 0:935006092f33 | 30 | //static uint8_t hcpCounter = 99; |
hemddabral | 0:935006092f33 | 31 | static uint8_t hcp[2] = {0x00, hrmCounter}; |
hemddabral | 0:935006092f33 | 32 | |
hemddabral | 0:935006092f33 | 33 | GattCharacteristic hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, bpm, sizeof(bpm), sizeof(bpm), |
hemddabral | 0:935006092f33 | 34 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
hemddabral | 0:935006092f33 | 35 | |
hemddabral | 0:935006092f33 | 36 | GattCharacteristic hcpControlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, hcp, sizeof(hcp), sizeof(hcp), |
hemddabral | 0:935006092f33 | 37 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| |
hemddabral | 0:935006092f33 | 38 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE); |
hemddabral | 0:935006092f33 | 39 | |
hemddabral | 0:935006092f33 | 40 | |
hemddabral | 0:935006092f33 | 41 | GattCharacteristic *hrmChars[] = {&hrmRate, &hcpControlPoint}; |
hemddabral | 0:935006092f33 | 42 | UUID HRMSERVICE(GattService::UUID_HEART_RATE_SERVICE); |
hemddabral | 0:935006092f33 | 43 | GattService hrmService(HRMSERVICE/*GattService::UUID_HEART_RATE_SERVICE*/, hrmChars, sizeof(hrmChars) / sizeof(GattCharacteristic *)); |
hemddabral | 0:935006092f33 | 44 | |
hemddabral | 1:857e59bbf707 | 45 | /* BP Service definition */ |
hemddabral | 0:935006092f33 | 46 | static uint8_t bpValue = 110; |
hemddabral | 0:935006092f33 | 47 | static uint8_t bloodPressure[2] = {bpValue, 0x00}; |
hemddabral | 0:935006092f33 | 48 | static uint8_t bpDevFeature[2] = {0x00, bpValue}; |
hemddabral | 0:935006092f33 | 49 | |
hemddabral | 0:935006092f33 | 50 | GattCharacteristic bpMeasurment(GattCharacteristic::UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR, bloodPressure, sizeof(bloodPressure), sizeof(bloodPressure), |
hemddabral | 0:935006092f33 | 51 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
hemddabral | 0:935006092f33 | 52 | |
hemddabral | 0:935006092f33 | 53 | GattCharacteristic bpFeature(GattCharacteristic::UUID_BLOOD_PRESSURE_FEATURE_CHAR, bpDevFeature, sizeof(bpDevFeature), sizeof(bpDevFeature), |
hemddabral | 0:935006092f33 | 54 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| |
hemddabral | 0:935006092f33 | 55 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE); |
hemddabral | 0:935006092f33 | 56 | |
hemddabral | 0:935006092f33 | 57 | |
hemddabral | 0:935006092f33 | 58 | GattCharacteristic *bpChars[] = {&bpMeasurment, &bpFeature}; |
hemddabral | 0:935006092f33 | 59 | UUID BP_SERVICE(GattService::UUID_BLOOD_PRESSURE_SERVICE); |
hemddabral | 0:935006092f33 | 60 | GattService bpService(BP_SERVICE, bpChars, sizeof(bpChars) / sizeof(GattCharacteristic *)); |
hemddabral | 0:935006092f33 | 61 | |
hemddabral | 1:857e59bbf707 | 62 | |
hemddabral | 1:857e59bbf707 | 63 | /* battery Service definition */ |
hemddabral | 1:857e59bbf707 | 64 | static uint8_t batteryValue = 0; |
hemddabral | 1:857e59bbf707 | 65 | static uint8_t batteryCharge[3] = {batteryValue, 0x00, 0x00}; |
hemddabral | 1:857e59bbf707 | 66 | static uint8_t batteryState[2] = {0x00, batteryValue}; |
hemddabral | 1:857e59bbf707 | 67 | |
hemddabral | 1:857e59bbf707 | 68 | GattCharacteristic batteryChargeChar(GattCharacteristic::UUID_BATTERY_LEVEL_STATE_CHAR, batteryCharge, sizeof(batteryCharge), sizeof(batteryCharge), |
hemddabral | 1:857e59bbf707 | 69 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
hemddabral | 1:857e59bbf707 | 70 | |
hemddabral | 1:857e59bbf707 | 71 | GattCharacteristic batteryPowerState(GattCharacteristic::UUID_BATTERY_POWER_STATE_CHAR, batteryState, sizeof(batteryState), sizeof(batteryState), |
hemddabral | 1:857e59bbf707 | 72 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| |
hemddabral | 1:857e59bbf707 | 73 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE); |
hemddabral | 1:857e59bbf707 | 74 | |
hemddabral | 1:857e59bbf707 | 75 | |
hemddabral | 1:857e59bbf707 | 76 | GattCharacteristic *batteryChars[] = {&batteryChargeChar, &batteryPowerState}; |
hemddabral | 1:857e59bbf707 | 77 | UUID BATTERY_SERVICE(GattService::UUID_BATTERY_SERVICE); |
hemddabral | 1:857e59bbf707 | 78 | GattService batteryService(BATTERY_SERVICE, batteryChars, sizeof(batteryChars) / sizeof(GattCharacteristic *)); |
hemddabral | 1:857e59bbf707 | 79 | |
hemddabral | 1:857e59bbf707 | 80 | |
hemddabral | 1:857e59bbf707 | 81 | static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE, GattService::UUID_BLOOD_PRESSURE_SERVICE, GattService::UUID_BATTERY_SERVICE}; |
hemddabral | 0:935006092f33 | 82 | |
hemddabral | 0:935006092f33 | 83 | |
hemddabral | 0:935006092f33 | 84 | void disconnectionCallback(Gap::Handle_t handle) |
hemddabral | 0:935006092f33 | 85 | { |
hemddabral | 0:935006092f33 | 86 | DEBUG("Disconnected!\n\r"); |
hemddabral | 0:935006092f33 | 87 | DEBUG("Restarting the advertising process\n\r"); |
hemddabral | 0:935006092f33 | 88 | dev.startAdvertising(); |
hemddabral | 0:935006092f33 | 89 | } |
hemddabral | 0:935006092f33 | 90 | |
hemddabral | 0:935006092f33 | 91 | void onWriteCallback(uint16_t attributeHandle) { |
hemddabral | 0:935006092f33 | 92 | DEBUG("Write Callback!!\n\r"); |
hemddabral | 0:935006092f33 | 93 | } |
hemddabral | 0:935006092f33 | 94 | |
hemddabral | 0:935006092f33 | 95 | void onConnectionCallback(Gap::Handle_t handle) { |
hemddabral | 0:935006092f33 | 96 | //myled = 1; // LED is ON |
hemddabral | 0:935006092f33 | 97 | DEBUG("Connected BlueNRG!!\n\r"); |
hemddabral | 0:935006092f33 | 98 | } |
hemddabral | 0:935006092f33 | 99 | |
hemddabral | 0:935006092f33 | 100 | void Append128bitUUID(uint8_t *array, const LongUUID_t SERVICE_UUID_128) |
hemddabral | 0:935006092f33 | 101 | { |
hemddabral | 0:935006092f33 | 102 | for(int x=0;x<16; x++) |
hemddabral | 0:935006092f33 | 103 | { |
hemddabral | 0:935006092f33 | 104 | array[x+UUID_Count*16]=SERVICE_UUID_128[x]; |
hemddabral | 0:935006092f33 | 105 | } |
hemddabral | 0:935006092f33 | 106 | UUID_Count++; |
hemddabral | 0:935006092f33 | 107 | return; |
hemddabral | 0:935006092f33 | 108 | } |
hemddabral | 0:935006092f33 | 109 | |
hemddabral | 0:935006092f33 | 110 | /** |
hemddabral | 0:935006092f33 | 111 | * Triggered periodically by the 'ticker' interrupt; updates hrmCounter. |
hemddabral | 0:935006092f33 | 112 | */ |
hemddabral | 0:935006092f33 | 113 | void periodicCallback(void) |
hemddabral | 0:935006092f33 | 114 | { |
hemddabral | 0:935006092f33 | 115 | //myled = !myled; /* Do blinky on LED1 while we're waiting for BLE events */ |
hemddabral | 0:935006092f33 | 116 | |
hemddabral | 0:935006092f33 | 117 | if (dev.getGapState().connected) { |
hemddabral | 0:935006092f33 | 118 | hrmCounter++; |
hemddabral | 0:935006092f33 | 119 | if (hrmCounter == 175) { |
hemddabral | 0:935006092f33 | 120 | hrmCounter = 100; |
hemddabral | 0:935006092f33 | 121 | } |
hemddabral | 0:935006092f33 | 122 | bpm[1] = hrmCounter; |
hemddabral | 0:935006092f33 | 123 | //uint16_t t = sizeof(bpm); |
hemddabral | 0:935006092f33 | 124 | //DEBUG("Char Handle 0x%x OK.",hrmRate.getHandle()); |
hemddabral | 0:935006092f33 | 125 | //dev.readCharacteristicValue(hrmRate.getHandle(), bpm, (uint16_t *const)t); |
hemddabral | 0:935006092f33 | 126 | dev.updateCharacteristicValue(hrmRate.getHandle(), bpm, sizeof(bpm)); |
hemddabral | 0:935006092f33 | 127 | |
hemddabral | 0:935006092f33 | 128 | bloodPressure[0] = hrmCounter; |
hemddabral | 0:935006092f33 | 129 | dev.updateCharacteristicValue(bpMeasurment.getHandle(), bloodPressure, sizeof(bloodPressure)); |
hemddabral | 0:935006092f33 | 130 | //DEBUG("Ticker CB..\n\r"); |
hemddabral | 1:857e59bbf707 | 131 | |
hemddabral | 1:857e59bbf707 | 132 | batteryValue++; |
hemddabral | 1:857e59bbf707 | 133 | batteryCharge[0] = (batteryValue+100)%100; |
hemddabral | 1:857e59bbf707 | 134 | dev.updateCharacteristicValue(batteryChargeChar.getHandle(), batteryCharge, sizeof(batteryCharge)); |
hemddabral | 0:935006092f33 | 135 | } //else DEBUG("Not Connected..\n\r"); |
hemddabral | 0:935006092f33 | 136 | } |
hemddabral | 0:935006092f33 | 137 | |
hemddabral | 0:935006092f33 | 138 | void multipleServiceUseCase() { |
hemddabral | 0:935006092f33 | 139 | Ticker ticker; //For Tick interrupt if used later on (periodic data updates?) |
hemddabral | 0:935006092f33 | 140 | |
hemddabral | 0:935006092f33 | 141 | |
hemddabral | 0:935006092f33 | 142 | //LongUUID_t HEART_RATE_CHAR_UUID_128, HRM_SERVICE_UUID_128; |
hemddabral | 0:935006092f33 | 143 | //COPY_HRM_SERVICE_UUID(HRM_SERVICE_UUID_128); |
hemddabral | 0:935006092f33 | 144 | //COPY_HRM_CHAR_UUID(HEART_RATE_CHAR_UUID_128); |
hemddabral | 0:935006092f33 | 145 | UUID heart_rate_char_UUID = UUID(HEART_RATE_CHAR_UUID_128); |
hemddabral | 0:935006092f33 | 146 | UUID hrm_service_UUID = UUID(HRM_SERVICE_UUID_128); |
hemddabral | 0:935006092f33 | 147 | |
hemddabral | 0:935006092f33 | 148 | myled = 0;//Switch OFF LED1 |
hemddabral | 0:935006092f33 | 149 | |
hemddabral | 0:935006092f33 | 150 | DEBUG("Initializing BlueNRG...\n\r"); |
hemddabral | 0:935006092f33 | 151 | #if 0 |
hemddabral | 0:935006092f33 | 152 | SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk |
hemddabral | 0:935006092f33 | 153 | DigitalOut cs(PB_6); |
hemddabral | 0:935006092f33 | 154 | cs = 0; |
hemddabral | 0:935006092f33 | 155 | #endif |
hemddabral | 0:935006092f33 | 156 | dev.init(); |
hemddabral | 0:935006092f33 | 157 | |
hemddabral | 0:935006092f33 | 158 | dev.onConnection(onConnectionCallback); |
hemddabral | 0:935006092f33 | 159 | dev.onDisconnection(disconnectionCallback); |
hemddabral | 0:935006092f33 | 160 | dev.onDataWritten(onWriteCallback); |
hemddabral | 0:935006092f33 | 161 | |
hemddabral | 0:935006092f33 | 162 | //TODO. |
hemddabral | 0:935006092f33 | 163 | //dev.setAddress(Gap::ADDR_TYPE_PUBLIC, device_address);//Does not work after gap/gatt init. |
hemddabral | 0:935006092f33 | 164 | //TODO. |
hemddabral | 0:935006092f33 | 165 | |
hemddabral | 0:935006092f33 | 166 | //Append128bitUUID(uuid128_list, HRM_SERVICE_UUID_128); |
hemddabral | 0:935006092f33 | 167 | |
hemddabral | 0:935006092f33 | 168 | /* setup advertising */ |
hemddabral | 0:935006092f33 | 169 | dev.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
hemddabral | 0:935006092f33 | 170 | |
hemddabral | 0:935006092f33 | 171 | //TODO:IMP STUFF: 128bit list is basically a uint8_t list. User should know how many services he supports and define the number in MAX_SERVICES_NOS |
hemddabral | 1:857e59bbf707 | 172 | dev.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list)); |
hemddabral | 0:935006092f33 | 173 | |
hemddabral | 0:935006092f33 | 174 | dev.accumulateAdvertisingPayload(GapAdvertisingData::HEART_RATE_SENSOR_HEART_RATE_BELT); |
hemddabral | 0:935006092f33 | 175 | |
hemddabral | 0:935006092f33 | 176 | dev.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
hemddabral | 0:935006092f33 | 177 | dev.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
hemddabral | 0:935006092f33 | 178 | dev.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ |
hemddabral | 0:935006092f33 | 179 | DEBUG("Starting Advertising...\n\r"); |
hemddabral | 0:935006092f33 | 180 | dev.startAdvertising(); |
hemddabral | 0:935006092f33 | 181 | |
hemddabral | 0:935006092f33 | 182 | |
hemddabral | 0:935006092f33 | 183 | dev.addService(bpService); |
hemddabral | 0:935006092f33 | 184 | dev.addService(hrmService); |
hemddabral | 1:857e59bbf707 | 185 | dev.addService(batteryService); |
hemddabral | 0:935006092f33 | 186 | |
hemddabral | 0:935006092f33 | 187 | |
hemddabral | 0:935006092f33 | 188 | //ticker.attach(periodicCallback, 1); Multi threading and called from ISR context does not work! |
hemddabral | 0:935006092f33 | 189 | |
hemddabral | 0:935006092f33 | 190 | while(1) { |
hemddabral | 0:935006092f33 | 191 | myled = 1; // LED is ON |
hemddabral | 0:935006092f33 | 192 | wait(0.5); // 500 ms |
hemddabral | 0:935006092f33 | 193 | myled = 0; // LED is OFF |
hemddabral | 0:935006092f33 | 194 | wait(0.5); // 500 ms |
hemddabral | 0:935006092f33 | 195 | //DEBUG("tic!\n\r"); |
hemddabral | 0:935006092f33 | 196 | periodicCallback();//Works from here!! |
hemddabral | 0:935006092f33 | 197 | |
hemddabral | 0:935006092f33 | 198 | dev.waitForEvent(); |
hemddabral | 0:935006092f33 | 199 | } |
hemddabral | 0:935006092f33 | 200 | } |
hemddabral | 0:935006092f33 | 201 |