init

Dependencies:   BLE_API mbed nRF51822

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "ble/BLE.h"
00019 #include "ble/services/HeartRateService.h"
00020 #include "ble/services/BatteryService.h"
00021 #include "ble/services/DeviceInformationService.h"
00022 #include "LEDService.h"
00023 #include "ButtonService.h"
00024 
00025 #define ASSERT_NO_FAILURE(CMD) do { \
00026                     ble_error_t error = (CMD); \
00027                     if (error == BLE_ERROR_NONE){ \
00028                         printf("{{success}}\r\n"); \
00029                     } else{ \
00030                         printf("{{failure}} %s at line %u ERROR CODE: %u\r\n", #CMD, __LINE__, (error)); \
00031                         return; \
00032                     } \
00033                     }while (0)
00034 #define CHECK_EQUALS(X,Y)    ((X)==(Y)) ? (printf("{{success}}\r\n")) : printf("{{failure}}\r\n");
00035 
00036 BLE                   ble;
00037 Gap::Address_t        address;
00038 GapAdvertisingData::Appearance appearance;
00039 
00040 const static char     DEVICE_NAME[] = "HRMTEST";
00041 static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE,
00042                                        GattService::UUID_DEVICE_INFORMATION_SERVICE,
00043                                        LEDService::LED_SERVICE_UUID};
00044 
00045 ButtonService *btnServicePtr;
00046 
00047 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
00048 {
00049     ble.gap().startAdvertising(); // restart advertising
00050 }
00051 
00052 void connectionCallback(const Gap::ConnectionCallbackParams_t *params){
00053     printf("Connected to: %d:%d:%d:%d:%d:%d\n",
00054            params->peerAddr[0], params->peerAddr[1], params->peerAddr[2], params->peerAddr[3], params->peerAddr[4], params->peerAddr[5]);
00055 }
00056 
00057 void testDeviceName()
00058 {
00059     if (ble.gap().getState().connected) {
00060         printf("Device must be disconnected\n");
00061         return;
00062     }
00063 
00064     uint8_t  deviceNameIn[] = "Josh-test";
00065     ASSERT_NO_FAILURE(ble.gap().setDeviceName(deviceNameIn));
00066     wait(0.5);
00067 
00068     const size_t MAX_DEVICE_NAME_LEN = 50;
00069     uint8_t  deviceName[MAX_DEVICE_NAME_LEN];
00070     unsigned length = MAX_DEVICE_NAME_LEN;
00071     ASSERT_NO_FAILURE(ble.gap().getDeviceName(deviceName, &length));
00072     printf("ASSERTIONS DONE\r\n");
00073     for (unsigned i = 0; i < length; i++) {
00074         printf("%c", deviceName[i]);
00075     }
00076     printf("\r\n");
00077     for (unsigned i = 0; i < strlen((char *)deviceNameIn); i++) {
00078         printf("%c", deviceNameIn[i]);
00079     }
00080     printf("\r\n");
00081 }
00082 
00083 void testAppearance()
00084 {
00085     if ((ble.gap().getState().connected)) {
00086         printf("Device must be disconnected\n");
00087         return;
00088     }
00089 
00090     ASSERT_NO_FAILURE(ble.gap().setAppearance(GapAdvertisingData::GENERIC_PHONE));
00091     ASSERT_NO_FAILURE(ble.gap().getAppearance(&appearance));
00092     printf("ASSERTIONS DONE\r\n");
00093     printf("%d\r\n", appearance);
00094 }
00095 
00096 void connParams()
00097 {
00098     if ((ble.gap().getState().connected)) {
00099         printf("Device must be disconnected\n");
00100         return;
00101     }
00102 
00103     Gap::ConnectionParams_t params;
00104     Gap::ConnectionParams_t paramsOut = {50, 500, 0, 500};
00105     Gap::ConnectionParams_t temp;
00106 
00107     ASSERT_NO_FAILURE(ble.gap().getPreferredConnectionParams(&temp));
00108     ASSERT_NO_FAILURE(ble.gap().setPreferredConnectionParams(&paramsOut));
00109     
00110     printf("ASSERTIONS DONE\r\n");
00111     
00112     ble.gap().getPreferredConnectionParams(&params);
00113 
00114     printf("%d\n", params.minConnectionInterval);
00115     printf("%d\n", params.maxConnectionInterval);
00116     printf("%d\n", params.slaveLatency);
00117     printf("%d\n", params.connectionSupervisionTimeout);
00118 
00119     ble.gap().setPreferredConnectionParams(&temp);
00120 }
00121 
00122 void notificationTest(void) {
00123     btnServicePtr->updateButtonState(true);
00124 }
00125 
00126 void commandInterpreter(void)
00127 {
00128     const static size_t MAX_SIZEOF_COMMAND = 50;
00129     while (true) {
00130         char command[MAX_SIZEOF_COMMAND];
00131         scanf("%s", command);
00132 
00133         if (!strcmp(command, "setDeviceName")) {
00134             testDeviceName();
00135         } else if (!strcmp(command, "appearance")) {
00136             testAppearance();
00137         } else if (!strcmp(command, "connParam")) {
00138             connParams();
00139         } else if (!strcmp(command, "notification")) {
00140             notificationTest();
00141         }
00142     }
00143 }
00144 
00145 /**
00146  * @return 0 if basic assumptions are validated. Non-zero returns are used to
00147  *     terminate the second-level python script early.
00148  */
00149 unsigned verifyBasicAssumptions()
00150 {
00151     ble.gap().onDisconnection(disconnectionCallback);
00152     ble.gap().onConnection(connectionCallback);
00153 
00154     /* Setup advertising. */
00155     if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE)) {
00156         return 1;
00157     }
00158     if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list))) {
00159         return 1;
00160     }
00161     if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR)) {
00162         return 1;
00163     }
00164     if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME))) {
00165         return 1;
00166     }
00167     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00168     ble.gap().setAdvertisingInterval(1000); /* 1000ms */
00169 
00170     if (ble.gap().startAdvertising()) {
00171         return 1;
00172     }
00173     
00174     const char *version = ble.getVersion();
00175     printf("%s\r\n", version);
00176     if (!strcmp(version, "")) return 1;
00177     return 0;
00178 }
00179 
00180 int main(void)
00181 {
00182     unsigned errorCode = ble.init();
00183     if (errorCode == 0) {
00184         uint8_t                   hrmCounter = 100; // init HRM to 100bps
00185         HeartRateService         *hrService  = new HeartRateService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
00186 
00187         bool                      initialValueForLEDCharacteristic = false;
00188         LEDService               *ledService                       = new LEDService(ble, initialValueForLEDCharacteristic);
00189 
00190         DeviceInformationService *deviceInfo = new DeviceInformationService(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
00191         
00192         btnServicePtr = new ButtonService(ble, false); 
00193     }
00194     errorCode |= verifyBasicAssumptions();
00195     if (errorCode == 0) {
00196         printf("{{success}}\r\n{{end}}\r\n"); /* hand over control from the host test to the python script. */
00197     } else {
00198         printf("{{failure}}\r\n{{end}}\r\n"); /* hand over control from the host test to the python script. */
00199     }
00200 
00201     unsigned synchronize;
00202     scanf("%u", &synchronize);
00203 
00204     if (errorCode != 0) {
00205         printf("Initial basic assumptions failed\r\n");
00206         return -1;
00207     }
00208 
00209     Gap::AddressType_t addressType;
00210     ASSERT_NO_FAILURE(ble.gap().getAddress(&addressType, address));
00211 
00212     /* write out the MAC address to allow the second level python script to target this device. */
00213     printf("%d:%d:%d:%d:%d:%d\n", address[0], address[1], address[2], address[3], address[4], address[5]);
00214 
00215     commandInterpreter();
00216 }