A GattClient example based on ST BlueNRG driving an LED service exported by a BLE_LED peripheral. Shows scanning, connections, service-discovery, and reads/writes.
Dependencies: BLE_API X_NUCLEO_IDB0XA1 mbed
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 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/DiscoveredCharacteristic.h" 00020 #include "ble/DiscoveredService.h" 00021 00022 #define SCAN_INT 0x30 // 30 ms = 48 * 0.625 ms 00023 #define SCAN_WIND 0x30 // 30 ms = 48 * 0.625 ms 00024 00025 00026 const Gap::Address_t BLE_address_BE = {0xCC, 0x00, 0x00, 0xE1, 0x80, 0x02}; 00027 const Gap::Address_t BLE_peer_address_BE = {0xFD, 0x66, 0x05, 0x13, 0xBE, 0xBA}; 00028 00029 DiscoveredCharacteristic ledCharacteristic; 00030 00031 uint8_t toggledValue = 0; 00032 enum { 00033 READ = 0, 00034 WRITE, 00035 IDLE 00036 }; 00037 static volatile unsigned int triggerOp = IDLE; 00038 00039 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) 00040 { 00041 (void)params; 00042 printf("disconnected\n\r"); 00043 } 00044 00045 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { 00046 if (params->peerAddr[0] != BLE_peer_address_BE[0]) { 00047 return; 00048 } 00049 00050 printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", 00051 params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0], 00052 params->rssi, params->isScanResponse, params->type); 00053 00054 if(!params->isScanResponse) { 00055 BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL); 00056 } 00057 } 00058 00059 void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { 00060 printf("terminated SD for handle %u\r\n", connectionHandle); 00061 } 00062 00063 void serviceDiscoveryCallback(const DiscoveredService *service) { 00064 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 00065 printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); 00066 } else { 00067 printf("S UUID-"); 00068 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); 00069 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { 00070 printf("%02X", longUUIDBytes[i]); 00071 } 00072 printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); 00073 } 00074 } 00075 00076 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { 00077 //printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); 00078 if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */ 00079 //printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); 00080 ledCharacteristic = *characteristicP; 00081 triggerOp = READ; 00082 } 00083 } 00084 00085 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { 00086 uint16_t LED_SERVICE_UUID = 0xA000; 00087 uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001; 00088 00089 if (params->role == Gap::CENTRAL) { 00090 BLE &ble = BLE::Instance(); 00091 ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); 00092 ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, LED_SERVICE_UUID, LED_STATE_CHARACTERISTIC_UUID); 00093 } 00094 } 00095 00096 void triggerToggledWrite(const GattReadCallbackParams *response) { 00097 if (response->handle == ledCharacteristic.getValueHandle()) { 00098 #if 0 00099 printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); 00100 for (unsigned index = 0; index < response->len; index++) { 00101 printf("%c[%02x]", response->data[index], response->data[index]); 00102 } 00103 printf("\r\n"); 00104 #endif 00105 00106 toggledValue = response->data[0] ^ 0x1; 00107 triggerOp = WRITE; 00108 } 00109 } 00110 00111 void triggerRead(const GattWriteCallbackParams *response) { 00112 if (response->handle == ledCharacteristic.getValueHandle()) { 00113 triggerOp = READ; 00114 } 00115 } 00116 00117 /** 00118 * This function is called when the ble initialization process has failled 00119 */ 00120 void onBleInitError(BLE &ble, ble_error_t error) 00121 { 00122 /* Initialization error handling should go here */ 00123 } 00124 00125 /** 00126 * Callback triggered when the ble initialization process has finished 00127 */ 00128 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00129 { 00130 BLE& ble = params->ble; 00131 ble_error_t error = params->error; 00132 00133 if (error != BLE_ERROR_NONE) { 00134 /* In case of error, forward the error handling to onBleInitError */ 00135 onBleInitError(ble, error); 00136 return; 00137 } 00138 00139 /* Ensure that it is the default instance of BLE */ 00140 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 00141 return; 00142 } 00143 00144 // Set BT Address 00145 ble.gap().setAddress(BLEProtocol::AddressType::PUBLIC, BLE_address_BE); 00146 00147 ble.gap().onConnection(connectionCallback); 00148 ble.onDisconnection(disconnectionCallback); 00149 00150 ble.gattClient().onDataRead(triggerToggledWrite); 00151 ble.gattClient().onDataWrite(triggerRead); 00152 00153 ble.gap().setScanParams(SCAN_INT, SCAN_WIND); 00154 ble.gap().startScan(advertisementCallback); 00155 00156 // infinite loop 00157 while (1) { 00158 if (!ble.gattClient().isServiceDiscoveryActive()) { 00159 switch(triggerOp) { 00160 case READ: 00161 triggerOp = IDLE; 00162 ledCharacteristic.read(); 00163 break; 00164 case WRITE: 00165 triggerOp = IDLE; 00166 ledCharacteristic.write(1, &toggledValue); 00167 break; 00168 } 00169 } 00170 ble.waitForEvent(); 00171 } 00172 } 00173 00174 int main(void) 00175 { 00176 BLE::Instance().init(bleInitComplete); 00177 }
Generated on Sat Jul 30 2022 14:10:15 by 1.7.2