Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 <events/mbed_events.h> 00018 #include <mbed.h> 00019 #include "ble/BLE.h" 00020 #include "ble/DiscoveredCharacteristic.h" 00021 #include "ble/DiscoveredService.h" 00022 00023 DigitalOut alivenessLED(LED1, 1); 00024 static DiscoveredCharacteristic ledCharacteristic; 00025 static bool triggerLedCharacteristic; 00026 static const char PEER_NAME[] = "LED"; 00027 static EventQueue eventQueue(/* event count */ 128 * EVENTS_EVENT_SIZE); 00028 00029 void periodicCallback(void) { 00030 alivenessLED = !alivenessLED; /* Do blinky on LED1 while we're waiting for BLE events */ 00031 } 00032 00033 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { 00034 // parse the advertising payload, looking for data type COMPLETE_LOCAL_NAME 00035 // The advertising payload is a collection of key/value records where 00036 // byte 0: length of the record excluding this byte 00037 // byte 1: The key, it is the type of the data 00038 // byte [2..N] The value. N is equal to byte0 - 1 00039 for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { 00040 00041 const uint8_t record_length = params->advertisingData[i]; 00042 if (record_length == 0) { 00043 continue; 00044 } 00045 const uint8_t type = params->advertisingData[i + 1]; 00046 const uint8_t* value = params->advertisingData + i + 2; 00047 const uint8_t value_length = record_length - 1; 00048 00049 if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { 00050 if ((value_length == sizeof(PEER_NAME)) && (memcmp(value, PEER_NAME, value_length) == 0)) { 00051 printf( 00052 "adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", 00053 params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], 00054 params->peerAddr[1], params->peerAddr[0], params->rssi, params->isScanResponse, params->type 00055 ); 00056 BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); 00057 break; 00058 } 00059 } 00060 i += record_length; 00061 } 00062 } 00063 00064 void serviceDiscoveryCallback(const DiscoveredService *service) { 00065 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 00066 printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); 00067 } else { 00068 printf("S UUID-"); 00069 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); 00070 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { 00071 printf("%02x", longUUIDBytes[i]); 00072 } 00073 printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); 00074 } 00075 } 00076 00077 void updateLedCharacteristic(void) { 00078 if (!BLE::Instance().gattClient().isServiceDiscoveryActive()) { 00079 ledCharacteristic.read(); 00080 } 00081 } 00082 00083 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { 00084 printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); 00085 if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */ 00086 ledCharacteristic = *characteristicP; 00087 triggerLedCharacteristic = true; 00088 } 00089 } 00090 00091 void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { 00092 printf("terminated SD for handle %u\r\n", connectionHandle); 00093 if (triggerLedCharacteristic) { 00094 triggerLedCharacteristic = false; 00095 eventQueue.call(updateLedCharacteristic); 00096 } 00097 } 00098 00099 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { 00100 if (params->role == Gap::CENTRAL) { 00101 BLE &ble = BLE::Instance(); 00102 ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); 00103 ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0xa000, 0xa001); 00104 } 00105 } 00106 00107 void triggerToggledWrite(const GattReadCallbackParams *response) { 00108 00109 if (response->handle == ledCharacteristic.getValueHandle()) { 00110 printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); 00111 for (unsigned index = 0; index < response->len; index++) { 00112 printf("%c[%02x]", response->data[index], response->data[index]); 00113 } 00114 printf("\r\n"); 00115 00116 uint8_t toggledValue = response->data[0] ^ 0x1; 00117 ledCharacteristic.write(1, &toggledValue); 00118 } 00119 } 00120 00121 void triggerRead(const GattWriteCallbackParams *response) { 00122 if (response->handle == ledCharacteristic.getValueHandle()) { 00123 ledCharacteristic.read(); 00124 } 00125 } 00126 00127 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) { 00128 printf("disconnected\r\n"); 00129 /* Start scanning and try to connect again */ 00130 BLE::Instance().gap().startScan(advertisementCallback); 00131 } 00132 00133 void onBleInitError(BLE &ble, ble_error_t error) 00134 { 00135 /* Initialization error handling should go here */ 00136 printf("Initialization error\r\n"); 00137 } 00138 00139 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00140 { 00141 BLE& ble = params->ble; 00142 ble_error_t error = params->error; 00143 00144 if (error != BLE_ERROR_NONE) { 00145 /* In case of error, forward the error handling to onBleInitError */ 00146 onBleInitError(ble, error); 00147 return; 00148 } 00149 00150 /* Ensure that it is the default instance of BLE */ 00151 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 00152 return; 00153 } 00154 00155 ble.gap().onDisconnection(disconnectionCallback); 00156 ble.gap().onConnection(connectionCallback); 00157 ble.gattClient().onDataRead(triggerToggledWrite); 00158 ble.gattClient().onDataWrite(triggerRead); 00159 // scan interval: 400ms and scan window: 400ms. 00160 // Every 400ms the device will scan for 400ms 00161 // This means that the device will scan continuously. 00162 ble.gap().setScanParams(400, 400); 00163 ble.gap().startScan(advertisementCallback); 00164 } 00165 00166 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { 00167 BLE &ble = BLE::Instance(); 00168 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); 00169 } 00170 00171 00172 int main() 00173 { 00174 triggerLedCharacteristic = false; 00175 eventQueue.call_every(5000, periodicCallback); 00176 BLE &ble = BLE::Instance(); 00177 ble.onEventsToProcess(scheduleBleEventsProcessing); 00178 ble.init(bleInitComplete); 00179 eventQueue.dispatch_forever(); 00180 return 0; 00181 }
Generated on Tue Jul 12 2022 23:11:07 by
1.7.2