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-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 <events/mbed_events.h> 00018 #include "mbed.h" 00019 #include "ble/BLE.h" 00020 00021 static const int URI_MAX_LENGTH = 18; // Maximum size of service data in ADV packets 00022 00023 static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); 00024 00025 DigitalOut led1(LED1, 1); 00026 00027 void periodicCallback(void) 00028 { 00029 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ 00030 } 00031 00032 void decodeURI(const uint8_t* uriData, const size_t uriLen) 00033 { 00034 const char *prefixes[] = { 00035 "http://www.", 00036 "https://www.", 00037 "http://", 00038 "https://", 00039 "urn:uuid:" 00040 }; 00041 const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *); 00042 const char *suffixes[] = { 00043 ".com/", 00044 ".org/", 00045 ".edu/", 00046 ".net/", 00047 ".info/", 00048 ".biz/", 00049 ".gov/", 00050 ".com", 00051 ".org", 00052 ".edu", 00053 ".net", 00054 ".info", 00055 ".biz", 00056 ".gov" 00057 }; 00058 const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *); 00059 00060 size_t index = 0; 00061 00062 /* First byte is the URL Scheme. */ 00063 if (uriData[index] < NUM_PREFIXES) { 00064 printf("%s", prefixes[uriData[index]]); 00065 index++; 00066 } else { 00067 printf("URL Scheme was not encoded!"); 00068 return; 00069 } 00070 00071 /* From second byte onwards we can have a character or a suffix */ 00072 while(index < uriLen) { 00073 if (uriData[index] < NUM_SUFFIXES) { 00074 printf("%s", suffixes[uriData[index]]); 00075 } else { 00076 printf("%c", uriData[index]); 00077 } 00078 index++; 00079 } 00080 00081 printf("\n\r"); 00082 } 00083 00084 /* 00085 * This function is called every time we scan an advertisement. 00086 */ 00087 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) 00088 { 00089 struct AdvertisingData_t { 00090 uint8_t length; /* doesn't include itself */ 00091 GapAdvertisingData::DataType_t dataType; 00092 uint8_t data[1]; 00093 } AdvDataPacket; 00094 00095 struct ApplicationData_t { 00096 uint8_t applicationSpecificId[2]; 00097 uint8_t frameType; 00098 uint8_t advPowerLevels; 00099 uint8_t uriData[URI_MAX_LENGTH]; 00100 } AppDataPacket; 00101 00102 const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)] = {0xAA, 0xFE}; 00103 const uint8_t FRAME_TYPE_URL = 0x10; 00104 const uint8_t APPLICATION_DATA_OFFSET = sizeof(ApplicationData_t) + sizeof(AdvDataPacket.dataType) - sizeof(AppDataPacket.uriData); 00105 00106 AdvertisingData_t *pAdvData; 00107 size_t index = 0; 00108 while(index < params->advertisingDataLen) { 00109 pAdvData = (AdvertisingData_t *)¶ms->advertisingData[index]; 00110 if (pAdvData->dataType == GapAdvertisingData::SERVICE_DATA) { 00111 ApplicationData_t *pAppData = (ApplicationData_t *) pAdvData->data; 00112 if (!memcmp(pAppData->applicationSpecificId, BEACON_UUID, sizeof(BEACON_UUID)) && (pAppData->frameType == FRAME_TYPE_URL)) { 00113 decodeURI(pAppData->uriData, pAdvData->length - APPLICATION_DATA_OFFSET); 00114 break; 00115 } 00116 } 00117 index += (pAdvData->length + 1); 00118 } 00119 } 00120 00121 void onBleInitError(BLE &ble, ble_error_t error) 00122 { 00123 /* Initialization error handling should go here */ 00124 } 00125 00126 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00127 { 00128 BLE& ble = params->ble; 00129 ble_error_t error = params->error; 00130 00131 if (error != BLE_ERROR_NONE) { 00132 onBleInitError(ble, error); 00133 return; 00134 } 00135 00136 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 00137 return; 00138 } 00139 00140 ble.gap().setScanParams(1800 /* scan interval */, 1500 /* scan window */); 00141 ble.gap().startScan(advertisementCallback); 00142 } 00143 00144 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { 00145 BLE &ble = BLE::Instance(); 00146 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); 00147 } 00148 00149 int main() 00150 { 00151 eventQueue.call_every(500, periodicCallback); 00152 00153 BLE &ble = BLE::Instance(); 00154 ble.onEventsToProcess(scheduleBleEventsProcessing); 00155 ble.init(bleInitComplete); 00156 00157 eventQueue.dispatch_forever(); 00158 00159 return 0; 00160 }
Generated on Fri Jul 15 2022 06:27:28 by
1.7.2