Eddystone test using modified DAL
Dependencies: BLE_API mbed-dev-bin nRF51822
Dependents: microbit-eddystone
Fork of microbit-dal by
MicroBitEddystone.cpp
00001 /* 00002 The MIT License (MIT) 00003 00004 Copyright (c) 2016 British Broadcasting Corporation. 00005 This software is provided by Lancaster University by arrangement with the BBC. 00006 00007 Permission is hereby granted, free of charge, to any person obtaining a 00008 copy of this software and associated documentation files (the "Software"), 00009 to deal in the Software without restriction, including without limitation 00010 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 and/or sell copies of the Software, and to permit persons to whom the 00012 Software is furnished to do so, subject to the following conditions: 00013 00014 The above copyright notice and this permission notice shall be included in 00015 all copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00023 DEALINGS IN THE SOFTWARE. 00024 */ 00025 00026 #include "MicroBitConfig.h" 00027 #include "MicroBitEddystone.h" 00028 00029 MicroBitEddystone *MicroBitEddystone::_instance = NULL; 00030 00031 /* The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ. 00032 * If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL) 00033 * The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this 00034 * as a compatability option, but does not support the options used... 00035 */ 00036 #if !defined(__arm) 00037 #pragma GCC diagnostic ignored "-Wunused-function" 00038 #pragma GCC diagnostic push 00039 #pragma GCC diagnostic ignored "-Wunused-parameter" 00040 #endif 00041 00042 /* 00043 * Return to our predefined compiler settings. 00044 */ 00045 #if !defined(__arm) 00046 #pragma GCC diagnostic pop 00047 #endif 00048 00049 const uint8_t EDDYSTONE_UUID[] = {0xAA, 0xFE}; 00050 00051 #if CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_URL) 00052 const char *EDDYSTONE_URL_PREFIXES[] = {"http://www.", "https://www.", "http://", "https://"}; 00053 const size_t EDDYSTONE_URL_PREFIXES_LENGTH = sizeof(EDDYSTONE_URL_PREFIXES) / sizeof(char *); 00054 const char *EDDYSTONE_URL_SUFFIXES[] = {".com/", ".org/", ".edu/", ".net/", ".info/", ".biz/", ".gov/", ".com", ".org", ".edu", ".net", ".info", ".biz", ".gov"}; 00055 const size_t EDDYSTONE_URL_SUFFIXES_LENGTH = sizeof(EDDYSTONE_URL_SUFFIXES) / sizeof(char *); 00056 const int EDDYSTONE_URL_MAX_LENGTH = 18; 00057 const uint8_t EDDYSTONE_URL_FRAME_TYPE = 0x10; 00058 #endif 00059 00060 #if CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_UID) 00061 const int EDDYSTONE_UID_NAMESPACE_MAX_LENGTH = 10; 00062 const int EDDYSTONE_UID_INSTANCE_MAX_LENGTH = 6; 00063 const uint8_t EDDYSTONE_UID_FRAME_TYPE = 0x00; 00064 #endif 00065 00066 /** 00067 * Constructor. 00068 * 00069 * Configure and manage the micro:bit's Bluetooth Low Energy (BLE) stack. 00070 * 00071 * @param _storage an instance of MicroBitStorage used to persist sys attribute information. (This is required for compatability with iOS). 00072 * 00073 * @note The BLE stack *cannot* be brought up in a static context (the software simply hangs or corrupts itself). 00074 * Hence, the init() member function should be used to initialise the BLE stack. 00075 */ 00076 MicroBitEddystone::MicroBitEddystone() 00077 { 00078 } 00079 00080 MicroBitEddystone* MicroBitEddystone::getInstance() 00081 { 00082 if (_instance == 0) 00083 _instance = new MicroBitEddystone; 00084 00085 return _instance; 00086 } 00087 00088 #if CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_URL) 00089 00090 /** 00091 * Set the content of Eddystone URL frames 00092 * 00093 * @param url The url to broadcast 00094 * 00095 * @param calibratedPower the transmission range of the beacon (Defaults to: 0xF0 ~10m). 00096 * 00097 * @note The calibratedPower value ranges from -100 to +20 to a resolution of 1. The calibrated power should be binary encoded. 00098 * More information can be found at https://github.com/google/eddystone/tree/master/eddystone-uid#tx-power 00099 */ 00100 int MicroBitEddystone::setURL(BLEDevice* ble, const char* url, int8_t calibratedPower) 00101 { 00102 int urlDataLength = 0; 00103 char urlData[EDDYSTONE_URL_MAX_LENGTH]; 00104 memset(urlData, 0, EDDYSTONE_URL_MAX_LENGTH); 00105 00106 if (url == NULL || strlen(url) == 0) 00107 return MICROBIT_INVALID_PARAMETER; 00108 00109 // Prefix 00110 for (size_t i = 0; i < EDDYSTONE_URL_PREFIXES_LENGTH; i++) 00111 { 00112 size_t prefixLen = strlen(EDDYSTONE_URL_PREFIXES[i]); 00113 if (strncmp(url, EDDYSTONE_URL_PREFIXES[i], prefixLen) == 0) 00114 { 00115 urlData[urlDataLength++] = i; 00116 url += prefixLen; 00117 break; 00118 } 00119 } 00120 00121 // Suffix 00122 while (*url && (urlDataLength < EDDYSTONE_URL_MAX_LENGTH)) 00123 { 00124 size_t i; 00125 for (i = 0; i < EDDYSTONE_URL_SUFFIXES_LENGTH; i++) 00126 { 00127 size_t suffixLen = strlen(EDDYSTONE_URL_SUFFIXES[i]); 00128 if (strncmp(url, EDDYSTONE_URL_SUFFIXES[i], suffixLen) == 0) 00129 { 00130 urlData[urlDataLength++] = i; 00131 url += suffixLen; 00132 break; 00133 } 00134 } 00135 00136 // Catch the default case where the suffix doesn't match a preset ones 00137 if (i == EDDYSTONE_URL_SUFFIXES_LENGTH) 00138 { 00139 urlData[urlDataLength++] = *url; 00140 ++url; 00141 } 00142 } 00143 00144 uint8_t rawFrame[EDDYSTONE_URL_MAX_LENGTH + 4]; 00145 size_t index = 0; 00146 rawFrame[index++] = EDDYSTONE_UUID[0]; 00147 rawFrame[index++] = EDDYSTONE_UUID[1]; 00148 rawFrame[index++] = EDDYSTONE_URL_FRAME_TYPE; 00149 rawFrame[index++] = calibratedPower; 00150 memcpy(rawFrame + index, urlData, urlDataLength); 00151 00152 ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, EDDYSTONE_UUID, sizeof(EDDYSTONE_UUID)); 00153 ble->accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, rawFrame, index + urlDataLength); 00154 00155 return MICROBIT_OK; 00156 } 00157 00158 /** 00159 * Set the content of Eddystone URL frames, but accepts a ManagedString as a url. 00160 * 00161 * @param url The url to broadcast 00162 * 00163 * @param calibratedPower the transmission range of the beacon (Defaults to: 0xF0 ~10m). 00164 * 00165 * @note The calibratedPower value ranges from -100 to +20 to a resolution of 1. The calibrated power should be binary encoded. 00166 * More information can be found at https://github.com/google/eddystone/tree/master/eddystone-uid#tx-power 00167 */ 00168 int MicroBitEddystone::setURL(BLEDevice* ble, ManagedString url, int8_t calibratedPower) 00169 { 00170 return setURL(ble, (char *)url.toCharArray(), calibratedPower); 00171 } 00172 #endif 00173 00174 #if CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_UID) 00175 00176 /** 00177 * Set the content of Eddystone UID frames 00178 * 00179 * @param uid_namespace the uid namespace. Must 10 bytes long. 00180 * 00181 * @param uid_instance the uid instance value. Must 6 bytes long. 00182 * 00183 * @param calibratedPower the transmission range of the beacon (Defaults to: 0xF0 ~10m). 00184 * 00185 * @note The calibratedPower value ranges from -100 to +20 to a resolution of 1. The calibrated power should be binary encoded. 00186 * More information can be found at https://github.com/google/eddystone/tree/master/eddystone-uid#tx-power 00187 */ 00188 int MicroBitEddystone::setUID(BLEDevice* ble, const char* uid_namespace, const char* uid_instance, int8_t calibratedPower) 00189 { 00190 if (uid_namespace == NULL || uid_instance == NULL) 00191 return MICROBIT_INVALID_PARAMETER; 00192 00193 char uidData[EDDYSTONE_UID_NAMESPACE_MAX_LENGTH + EDDYSTONE_UID_INSTANCE_MAX_LENGTH]; 00194 00195 // UID namespace 00196 memcpy(uidData, uid_namespace, EDDYSTONE_UID_NAMESPACE_MAX_LENGTH); 00197 00198 // UID instance 00199 memcpy(uidData + EDDYSTONE_UID_NAMESPACE_MAX_LENGTH, uid_instance, EDDYSTONE_UID_INSTANCE_MAX_LENGTH); 00200 00201 uint8_t rawFrame[EDDYSTONE_UID_NAMESPACE_MAX_LENGTH + EDDYSTONE_UID_INSTANCE_MAX_LENGTH + 4]; 00202 size_t index = 0; 00203 rawFrame[index++] = EDDYSTONE_UUID[0]; 00204 rawFrame[index++] = EDDYSTONE_UUID[1]; 00205 rawFrame[index++] = EDDYSTONE_UID_FRAME_TYPE; 00206 rawFrame[index++] = calibratedPower; 00207 memcpy(rawFrame + index, uidData, EDDYSTONE_UID_NAMESPACE_MAX_LENGTH + EDDYSTONE_UID_INSTANCE_MAX_LENGTH); 00208 00209 ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, EDDYSTONE_UUID, sizeof(EDDYSTONE_UUID)); 00210 ble->accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, rawFrame, index + EDDYSTONE_UID_NAMESPACE_MAX_LENGTH + EDDYSTONE_UID_INSTANCE_MAX_LENGTH); 00211 00212 return MICROBIT_OK; 00213 } 00214 00215 #endif
Generated on Tue Jul 12 2022 21:07:40 by 1.7.2