Ken Ogami / microbit-dal

Dependencies:   BLE_API mbed-dev-bin nRF51822

Dependents:   microbit microbit

Fork of microbit-dal by Wendy Warne

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicroBitEddystone.cpp Source File

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 
00061 
00062 /**
00063  * Constructor.
00064  *
00065  * Configure and manage the micro:bit's Bluetooth Low Energy (BLE) stack.
00066  *
00067  * @param _storage an instance of MicroBitStorage used to persist sys attribute information. (This is required for compatability with iOS).
00068  *
00069  * @note The BLE stack *cannot*  be brought up in a static context (the software simply hangs or corrupts itself).
00070  * Hence, the init() member function should be used to initialise the BLE stack.
00071  */
00072 MicroBitEddystone::MicroBitEddystone()
00073 {
00074 }
00075 
00076 MicroBitEddystone* MicroBitEddystone::getInstance()
00077 {
00078     if (_instance == 0)
00079         _instance = new MicroBitEddystone;
00080 
00081     return _instance;
00082 }
00083 
00084 #if CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_URL)
00085 
00086 /**
00087   * Set the content of Eddystone URL frames
00088   * @param url The url to broadcast
00089   * @param calibratedPower the transmission range of the beacon (Defaults to: 0xF0 ~10m).
00090   * @note The calibratedPower value ranges from -100 to +20 to a resolution of 1. The calibrated power should be binary encoded.
00091   * More information can be found at https://github.com/google/eddystone/tree/master/eddystone-uid#tx-power
00092   */
00093 int MicroBitEddystone::setURL(BLEDevice* ble, const char* url, int8_t calibratedPower)
00094 {
00095     int urlDataLength = 0;
00096     char urlData[EDDYSTONE_URL_MAX_LENGTH];
00097     memset(urlData, 0, EDDYSTONE_URL_MAX_LENGTH);
00098 
00099     if (url == NULL || strlen(url) == 0)
00100         return MICROBIT_INVALID_PARAMETER;
00101 
00102     // Prefix
00103     for (size_t i = 0; i < EDDYSTONE_URL_PREFIXES_LENGTH; i++)
00104     {
00105         size_t prefixLen = strlen(EDDYSTONE_URL_PREFIXES[i]);
00106         if (strncmp(url, EDDYSTONE_URL_PREFIXES[i], prefixLen) == 0)
00107         {
00108             urlData[urlDataLength++] = i;
00109             url += prefixLen;
00110             break;
00111         }
00112     }
00113 
00114     // Suffix
00115     while (*url && (urlDataLength < EDDYSTONE_URL_MAX_LENGTH))
00116     {
00117         size_t i;
00118         for (i = 0; i < EDDYSTONE_URL_SUFFIXES_LENGTH; i++)
00119         {
00120             size_t suffixLen = strlen(EDDYSTONE_URL_SUFFIXES[i]);
00121             if (strncmp(url, EDDYSTONE_URL_SUFFIXES[i], suffixLen) == 0)
00122             {
00123                 urlData[urlDataLength++] = i;
00124                 url += suffixLen;
00125                 break;
00126             }
00127         }
00128 
00129         // Catch the default case where the suffix doesn't match a preset ones
00130         if (i == EDDYSTONE_URL_SUFFIXES_LENGTH)
00131         {
00132             urlData[urlDataLength++] = *url;
00133             ++url;
00134         }
00135     }
00136 
00137     uint8_t rawFrame[EDDYSTONE_URL_MAX_LENGTH + 4];
00138     size_t index = 0;
00139     rawFrame[index++] = EDDYSTONE_UUID[0];
00140     rawFrame[index++] = EDDYSTONE_UUID[1];
00141     rawFrame[index++] = EDDYSTONE_URL_FRAME_TYPE;
00142     rawFrame[index++] = calibratedPower;
00143     memcpy(rawFrame + index, urlData, urlDataLength);
00144 
00145     ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, EDDYSTONE_UUID, sizeof(EDDYSTONE_UUID));
00146     ble->accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, rawFrame, index + urlDataLength);
00147 
00148     return MICROBIT_OK;
00149 }
00150 
00151 /**
00152   * Set the content of Eddystone URL frames, but accepts a ManagedString as a url.
00153   * @param url The url to broadcast
00154   * @param calibratedPower the transmission range of the beacon (Defaults to: 0xF0 ~10m).
00155   * @note The calibratedPower value ranges from -100 to +20 to a resolution of 1. The calibrated power should be binary encoded.
00156   * More information can be found at https://github.com/google/eddystone/tree/master/eddystone-uid#tx-power
00157   */
00158 int MicroBitEddystone::setURL(BLEDevice* ble, ManagedString url, int8_t calibratedPower)
00159 {
00160     return setURL(ble, (char *)url.toCharArray(), calibratedPower);
00161 }
00162 #endif
00163