init

Dependencies:   BLE_API mbed nRF51822

Committer:
jslater8
Date:
Mon Aug 17 09:49:55 2015 +0000
Revision:
2:95c770f35636
Parent:
1:4bdebb81dcd5
Initial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jslater8 0:84779d0d1ff5 1 /* mbed Microcontroller Library
jslater8 0:84779d0d1ff5 2 * Copyright (c) 2006-2015 ARM Limited
jslater8 0:84779d0d1ff5 3 *
jslater8 0:84779d0d1ff5 4 * Licensed under the Apache License, Version 2.0 (the "License");
jslater8 0:84779d0d1ff5 5 * you may not use this file except in compliance with the License.
jslater8 0:84779d0d1ff5 6 * You may obtain a copy of the License at
jslater8 0:84779d0d1ff5 7 *
jslater8 0:84779d0d1ff5 8 * http://www.apache.org/licenses/LICENSE-2.0
jslater8 0:84779d0d1ff5 9 *
jslater8 0:84779d0d1ff5 10 * Unless required by applicable law or agreed to in writing, software
jslater8 0:84779d0d1ff5 11 * distributed under the License is distributed on an "AS IS" BASIS,
jslater8 0:84779d0d1ff5 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
jslater8 0:84779d0d1ff5 13 * See the License for the specific language governing permissions and
jslater8 0:84779d0d1ff5 14 * limitations under the License.
jslater8 0:84779d0d1ff5 15 */
jslater8 0:84779d0d1ff5 16
jslater8 0:84779d0d1ff5 17 #include "mbed.h"
jslater8 0:84779d0d1ff5 18 #include "ble/BLE.h"
jslater8 0:84779d0d1ff5 19 #include "ble/services/HeartRateService.h"
jslater8 0:84779d0d1ff5 20 #include "ble/services/BatteryService.h"
jslater8 0:84779d0d1ff5 21 #include "ble/services/DeviceInformationService.h"
jslater8 0:84779d0d1ff5 22 #include "LEDService.h"
jslater8 2:95c770f35636 23 #include "ButtonService.h"
jslater8 0:84779d0d1ff5 24
jslater8 2:95c770f35636 25 #define ASSERT_NO_FAILURE(CMD) do { \
jslater8 2:95c770f35636 26 ble_error_t error = (CMD); \
jslater8 2:95c770f35636 27 if (error == BLE_ERROR_NONE){ \
jslater8 2:95c770f35636 28 printf("{{success}}\r\n"); \
jslater8 2:95c770f35636 29 } else{ \
jslater8 2:95c770f35636 30 printf("{{failure}} %s at line %u ERROR CODE: %u\r\n", #CMD, __LINE__, (error)); \
jslater8 2:95c770f35636 31 return; \
jslater8 2:95c770f35636 32 } \
jslater8 2:95c770f35636 33 }while (0)
jslater8 2:95c770f35636 34 #define CHECK_EQUALS(X,Y) ((X)==(Y)) ? (printf("{{success}}\r\n")) : printf("{{failure}}\r\n");
jslater8 0:84779d0d1ff5 35
jslater8 2:95c770f35636 36 BLE ble;
jslater8 2:95c770f35636 37 Gap::Address_t address;
jslater8 2:95c770f35636 38 GapAdvertisingData::Appearance appearance;
jslater8 2:95c770f35636 39
jslater8 2:95c770f35636 40 const static char DEVICE_NAME[] = "HRMTEST";
jslater8 2:95c770f35636 41 static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE,
jslater8 2:95c770f35636 42 GattService::UUID_DEVICE_INFORMATION_SERVICE,
jslater8 2:95c770f35636 43 LEDService::LED_SERVICE_UUID};
jslater8 2:95c770f35636 44
jslater8 2:95c770f35636 45 ButtonService *btnServicePtr;
jslater8 0:84779d0d1ff5 46
jslater8 0:84779d0d1ff5 47 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
jslater8 0:84779d0d1ff5 48 {
jslater8 0:84779d0d1ff5 49 ble.gap().startAdvertising(); // restart advertising
jslater8 0:84779d0d1ff5 50 }
jslater8 0:84779d0d1ff5 51
jslater8 2:95c770f35636 52 void connectionCallback(const Gap::ConnectionCallbackParams_t *params){
jslater8 2:95c770f35636 53 printf("Connected to: %d:%d:%d:%d:%d:%d\n",
jslater8 2:95c770f35636 54 params->peerAddr[0], params->peerAddr[1], params->peerAddr[2], params->peerAddr[3], params->peerAddr[4], params->peerAddr[5]);
jslater8 0:84779d0d1ff5 55 }
jslater8 0:84779d0d1ff5 56
jslater8 2:95c770f35636 57 void testDeviceName()
jslater8 2:95c770f35636 58 {
jslater8 2:95c770f35636 59 if (ble.gap().getState().connected) {
jslater8 1:4bdebb81dcd5 60 printf("Device must be disconnected\n");
jslater8 1:4bdebb81dcd5 61 return;
jslater8 1:4bdebb81dcd5 62 }
jslater8 2:95c770f35636 63
jslater8 2:95c770f35636 64 uint8_t deviceNameIn[] = "Josh-test";
jslater8 2:95c770f35636 65 ASSERT_NO_FAILURE(ble.gap().setDeviceName(deviceNameIn));
jslater8 1:4bdebb81dcd5 66 wait(0.5);
jslater8 2:95c770f35636 67
jslater8 2:95c770f35636 68 const size_t MAX_DEVICE_NAME_LEN = 50;
jslater8 2:95c770f35636 69 uint8_t deviceName[MAX_DEVICE_NAME_LEN];
jslater8 2:95c770f35636 70 unsigned length = MAX_DEVICE_NAME_LEN;
jslater8 2:95c770f35636 71 ASSERT_NO_FAILURE(ble.gap().getDeviceName(deviceName, &length));
jslater8 2:95c770f35636 72 printf("ASSERTIONS DONE\r\n");
jslater8 2:95c770f35636 73 for (unsigned i = 0; i < length; i++) {
jslater8 2:95c770f35636 74 printf("%c", deviceName[i]);
jslater8 0:84779d0d1ff5 75 }
jslater8 0:84779d0d1ff5 76 printf("\r\n");
jslater8 2:95c770f35636 77 for (unsigned i = 0; i < strlen((char *)deviceNameIn); i++) {
jslater8 2:95c770f35636 78 printf("%c", deviceNameIn[i]);
jslater8 0:84779d0d1ff5 79 }
jslater8 0:84779d0d1ff5 80 printf("\r\n");
jslater8 0:84779d0d1ff5 81 }
jslater8 0:84779d0d1ff5 82
jslater8 2:95c770f35636 83 void testAppearance()
jslater8 2:95c770f35636 84 {
jslater8 2:95c770f35636 85 if ((ble.gap().getState().connected)) {
jslater8 1:4bdebb81dcd5 86 printf("Device must be disconnected\n");
jslater8 1:4bdebb81dcd5 87 return;
jslater8 1:4bdebb81dcd5 88 }
jslater8 0:84779d0d1ff5 89
jslater8 2:95c770f35636 90 ASSERT_NO_FAILURE(ble.gap().setAppearance(GapAdvertisingData::GENERIC_PHONE));
jslater8 2:95c770f35636 91 ASSERT_NO_FAILURE(ble.gap().getAppearance(&appearance));
jslater8 2:95c770f35636 92 printf("ASSERTIONS DONE\r\n");
jslater8 2:95c770f35636 93 printf("%d\r\n", appearance);
jslater8 2:95c770f35636 94 }
jslater8 2:95c770f35636 95
jslater8 2:95c770f35636 96 void connParams()
jslater8 2:95c770f35636 97 {
jslater8 2:95c770f35636 98 if ((ble.gap().getState().connected)) {
jslater8 1:4bdebb81dcd5 99 printf("Device must be disconnected\n");
jslater8 1:4bdebb81dcd5 100 return;
jslater8 1:4bdebb81dcd5 101 }
jslater8 2:95c770f35636 102
jslater8 0:84779d0d1ff5 103 Gap::ConnectionParams_t params;
jslater8 2:95c770f35636 104 Gap::ConnectionParams_t paramsOut = {50, 500, 0, 500};
jslater8 0:84779d0d1ff5 105 Gap::ConnectionParams_t temp;
jslater8 2:95c770f35636 106
jslater8 2:95c770f35636 107 ASSERT_NO_FAILURE(ble.gap().getPreferredConnectionParams(&temp));
jslater8 2:95c770f35636 108 ASSERT_NO_FAILURE(ble.gap().setPreferredConnectionParams(&paramsOut));
jslater8 2:95c770f35636 109
jslater8 2:95c770f35636 110 printf("ASSERTIONS DONE\r\n");
jslater8 2:95c770f35636 111
jslater8 0:84779d0d1ff5 112 ble.gap().getPreferredConnectionParams(&params);
jslater8 2:95c770f35636 113
jslater8 0:84779d0d1ff5 114 printf("%d\n", params.minConnectionInterval);
jslater8 0:84779d0d1ff5 115 printf("%d\n", params.maxConnectionInterval);
jslater8 0:84779d0d1ff5 116 printf("%d\n", params.slaveLatency);
jslater8 0:84779d0d1ff5 117 printf("%d\n", params.connectionSupervisionTimeout);
jslater8 2:95c770f35636 118
jslater8 0:84779d0d1ff5 119 ble.gap().setPreferredConnectionParams(&temp);
jslater8 2:95c770f35636 120 }
jslater8 2:95c770f35636 121
jslater8 2:95c770f35636 122 void notificationTest(void) {
jslater8 2:95c770f35636 123 btnServicePtr->updateButtonState(true);
jslater8 2:95c770f35636 124 }
jslater8 2:95c770f35636 125
jslater8 2:95c770f35636 126 void commandInterpreter(void)
jslater8 2:95c770f35636 127 {
jslater8 2:95c770f35636 128 const static size_t MAX_SIZEOF_COMMAND = 50;
jslater8 2:95c770f35636 129 while (true) {
jslater8 2:95c770f35636 130 char command[MAX_SIZEOF_COMMAND];
jslater8 2:95c770f35636 131 scanf("%s", command);
jslater8 2:95c770f35636 132
jslater8 2:95c770f35636 133 if (!strcmp(command, "setDeviceName")) {
jslater8 2:95c770f35636 134 testDeviceName();
jslater8 2:95c770f35636 135 } else if (!strcmp(command, "appearance")) {
jslater8 2:95c770f35636 136 testAppearance();
jslater8 2:95c770f35636 137 } else if (!strcmp(command, "connParam")) {
jslater8 2:95c770f35636 138 connParams();
jslater8 2:95c770f35636 139 } else if (!strcmp(command, "notification")) {
jslater8 2:95c770f35636 140 notificationTest();
jslater8 2:95c770f35636 141 }
jslater8 2:95c770f35636 142 }
jslater8 2:95c770f35636 143 }
jslater8 0:84779d0d1ff5 144
jslater8 2:95c770f35636 145 /**
jslater8 2:95c770f35636 146 * @return 0 if basic assumptions are validated. Non-zero returns are used to
jslater8 2:95c770f35636 147 * terminate the second-level python script early.
jslater8 2:95c770f35636 148 */
jslater8 2:95c770f35636 149 unsigned verifyBasicAssumptions()
jslater8 2:95c770f35636 150 {
jslater8 2:95c770f35636 151 ble.gap().onDisconnection(disconnectionCallback);
jslater8 2:95c770f35636 152 ble.gap().onConnection(connectionCallback);
jslater8 2:95c770f35636 153
jslater8 2:95c770f35636 154 /* Setup advertising. */
jslater8 2:95c770f35636 155 if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE)) {
jslater8 2:95c770f35636 156 return 1;
jslater8 2:95c770f35636 157 }
jslater8 2:95c770f35636 158 if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list))) {
jslater8 2:95c770f35636 159 return 1;
jslater8 0:84779d0d1ff5 160 }
jslater8 2:95c770f35636 161 if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR)) {
jslater8 2:95c770f35636 162 return 1;
jslater8 2:95c770f35636 163 }
jslater8 2:95c770f35636 164 if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME))) {
jslater8 2:95c770f35636 165 return 1;
jslater8 2:95c770f35636 166 }
jslater8 2:95c770f35636 167 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
jslater8 2:95c770f35636 168 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
jslater8 2:95c770f35636 169
jslater8 2:95c770f35636 170 if (ble.gap().startAdvertising()) {
jslater8 2:95c770f35636 171 return 1;
jslater8 2:95c770f35636 172 }
jslater8 2:95c770f35636 173
jslater8 2:95c770f35636 174 const char *version = ble.getVersion();
jslater8 2:95c770f35636 175 printf("%s\r\n", version);
jslater8 2:95c770f35636 176 if (!strcmp(version, "")) return 1;
jslater8 2:95c770f35636 177 return 0;
jslater8 0:84779d0d1ff5 178 }
jslater8 0:84779d0d1ff5 179
jslater8 0:84779d0d1ff5 180 int main(void)
jslater8 0:84779d0d1ff5 181 {
jslater8 2:95c770f35636 182 unsigned errorCode = ble.init();
jslater8 2:95c770f35636 183 if (errorCode == 0) {
jslater8 2:95c770f35636 184 uint8_t hrmCounter = 100; // init HRM to 100bps
jslater8 2:95c770f35636 185 HeartRateService *hrService = new HeartRateService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
jslater8 2:95c770f35636 186
jslater8 2:95c770f35636 187 bool initialValueForLEDCharacteristic = false;
jslater8 2:95c770f35636 188 LEDService *ledService = new LEDService(ble, initialValueForLEDCharacteristic);
jslater8 0:84779d0d1ff5 189
jslater8 2:95c770f35636 190 DeviceInformationService *deviceInfo = new DeviceInformationService(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
jslater8 2:95c770f35636 191
jslater8 2:95c770f35636 192 btnServicePtr = new ButtonService(ble, false);
jslater8 2:95c770f35636 193 }
jslater8 2:95c770f35636 194 errorCode |= verifyBasicAssumptions();
jslater8 2:95c770f35636 195 if (errorCode == 0) {
jslater8 2:95c770f35636 196 printf("{{success}}\r\n{{end}}\r\n"); /* hand over control from the host test to the python script. */
jslater8 2:95c770f35636 197 } else {
jslater8 2:95c770f35636 198 printf("{{failure}}\r\n{{end}}\r\n"); /* hand over control from the host test to the python script. */
jslater8 2:95c770f35636 199 }
jslater8 0:84779d0d1ff5 200
jslater8 2:95c770f35636 201 unsigned synchronize;
jslater8 2:95c770f35636 202 scanf("%u", &synchronize);
jslater8 0:84779d0d1ff5 203
jslater8 2:95c770f35636 204 if (errorCode != 0) {
jslater8 2:95c770f35636 205 printf("Initial basic assumptions failed\r\n");
jslater8 2:95c770f35636 206 return -1;
jslater8 2:95c770f35636 207 }
jslater8 2:95c770f35636 208
jslater8 2:95c770f35636 209 Gap::AddressType_t addressType;
jslater8 2:95c770f35636 210 ASSERT_NO_FAILURE(ble.gap().getAddress(&addressType, address));
jslater8 2:95c770f35636 211
jslater8 2:95c770f35636 212 /* write out the MAC address to allow the second level python script to target this device. */
jslater8 0:84779d0d1ff5 213 printf("%d:%d:%d:%d:%d:%d\n", address[0], address[1], address[2], address[3], address[4], address[5]);
jslater8 2:95c770f35636 214
jslater8 1:4bdebb81dcd5 215 commandInterpreter();
jslater8 0:84779d0d1ff5 216 }