Maxim Integrated / MaximBLE

Dependents:   BLE_Thermometer MAXWSNENV_demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MaximGap.cpp Source File

MaximGap.cpp

00001 /*******************************************************************************
00002  * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017  * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020  * OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  * Except as contained in this notice, the name of Maxim Integrated
00023  * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024  * Products, Inc. Branding Policy.
00025  *
00026  * The mere transfer of this software does not imply any licenses
00027  * of trade secrets, proprietary technology, copyrights, patents,
00028  * trademarks, maskwork rights, or any other form of intellectual
00029  * property whatsoever. Maxim Integrated Products, Inc. retains all
00030  * ownership rights.
00031  *******************************************************************************
00032  */
00033 
00034 #include "MaximGap.h"
00035 #include "mbed.h"
00036 #include "hci_vs.h"
00037 
00038 MaximGap &MaximGap::getInstance() {
00039     static MaximGap m_instance;
00040     return m_instance;
00041 }
00042 
00043 ble_error_t MaximGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
00044 {
00045     /* Make sure we don't exceed the advertising payload length */
00046     if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
00047         return BLE_ERROR_BUFFER_OVERFLOW;
00048     }
00049 
00050     /* Make sure we have a payload! */
00051     if (advData.getPayloadLen() == 0) {
00052         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00053     }
00054 
00055     /* save advertising and scan response data */
00056     advDataLen = advData.getPayloadLen();
00057     scanResponseLen = scanResponse.getPayloadLen();
00058     memcpy((void*)advDataCache, (void*)advData.getPayload(), advDataLen);
00059     memcpy((void*)advDataCache, (void*)advData.getPayload(), scanResponseLen);
00060 
00061     return BLE_ERROR_NONE;
00062 }
00063 
00064 ble_error_t MaximGap::startAdvertising(const GapAdvertisingParams &params)
00065 {
00066     /* Make sure we support the advertising type */
00067     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
00068         /* ToDo: This requires a proper security implementation, etc. */
00069         return BLE_ERROR_NOT_IMPLEMENTED;
00070     }
00071 
00072     /* Check interval range */
00073     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
00074         /* Min delay is slightly longer for unconnectable devices */
00075         if ((params.getInterval() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
00076             (params.getInterval() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
00077             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00078         }
00079     } else {
00080         if ((params.getInterval() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
00081             (params.getInterval() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
00082             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00083         }
00084     }
00085 
00086     /* Check timeout is zero for Connectable Directed */
00087     if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
00088         /* Timeout must be 0 with this type, although we'll never get here */
00089         /* since this isn't implemented yet anyway */
00090         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00091     }
00092 
00093     /* Check timeout for other advertising types */
00094     if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
00095         (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
00096         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00097     }
00098 
00099     /* set advertising and scan response data for discoverable mode */
00100     DmAdvSetData(DM_DATA_LOC_ADV, advDataLen, advDataCache);
00101     DmAdvSetData(DM_DATA_LOC_SCAN, scanResponseLen, scanResponseCache);
00102 
00103     DmAdvSetInterval(params.getInterval(), params.getInterval());
00104     DmAdvStart(params.getAdvertisingType(), params.getTimeout());
00105 
00106     state.advertising = 1;
00107 
00108     return BLE_ERROR_NONE;
00109 }
00110 
00111 ble_error_t MaximGap::stopAdvertising(void)
00112 {
00113     DmAdvStop();
00114 
00115     state.advertising = 0;
00116 
00117     return BLE_ERROR_NONE;
00118 }
00119 
00120 void MaximGap::advertisingStopped(void)
00121 {
00122     /* If advertising stopped due to a call to stopAdvertising(), state.advertising will
00123      * be '0.' Otherwise, advertising must have stopped due to a timeout
00124      */
00125     if (state.advertising) {
00126         processTimeoutEvent(Gap::TIMEOUT_SRC_ADVERTISING);
00127     }
00128 }
00129 
00130 ble_error_t MaximGap::disconnect(DisconnectionReason_t reason)
00131 {
00132     DmConnClose(DM_CLIENT_ID_APP, m_connectionHandle, reason);
00133 
00134     state.advertising = 0;
00135     state.connected = 0;
00136 
00137     return BLE_ERROR_NONE;
00138 }
00139 
00140 ble_error_t MaximGap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason)
00141 {
00142     DmConnClose(DM_CLIENT_ID_APP, connectionHandle, reason);
00143 
00144     state.advertising = 0;
00145     state.connected = 0;
00146 
00147     return BLE_ERROR_NONE;
00148 }
00149 
00150 ble_error_t MaximGap::getPreferredConnectionParams(ConnectionParams_t *params)
00151 {
00152     return BLE_ERROR_NOT_IMPLEMENTED;
00153 }
00154 
00155 ble_error_t MaximGap::setPreferredConnectionParams(const ConnectionParams_t *params)
00156 {
00157     return BLE_ERROR_NOT_IMPLEMENTED;
00158 }
00159 
00160 ble_error_t MaximGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *newParams)
00161 {
00162     if (DmConnCheckIdle(handle) != 0) {
00163         return BLE_STACK_BUSY;
00164     }
00165 
00166     hciConnSpec_t  connSpec;
00167     connSpec.connIntervalMin = newParams->minConnectionInterval;
00168     connSpec.connIntervalMax = newParams->maxConnectionInterval;
00169     connSpec.connLatency = newParams->slaveLatency;
00170     connSpec.supTimeout = newParams->connectionSupervisionTimeout;
00171     DmConnUpdate(handle, &connSpec);
00172 
00173     return BLE_ERROR_NONE;
00174 }
00175 
00176 ble_error_t MaximGap::startRadioScan(const GapScanningParams &scanningParams)
00177 {
00178     DmScanSetInterval(scanningParams.getInterval(), scanningParams.getWindow());
00179 
00180     uint8_t scanType = scanningParams.getActiveScanning() ? DM_SCAN_TYPE_ACTIVE : DM_SCAN_TYPE_PASSIVE;
00181     uint32_t duration = (uint32_t)scanningParams.getTimeout() * 1000;
00182     if (duration > 0xFFFF) {
00183         // saturate to 16-bits
00184         duration = 0xFFFF;
00185     }
00186 
00187     DmScanStart(DM_DISC_MODE_NONE, scanType, TRUE, duration);
00188 
00189     return BLE_ERROR_NONE;
00190 }
00191 
00192 ble_error_t MaximGap::stopScan(void)
00193 {
00194     DmScanStop();
00195     return BLE_ERROR_NONE;
00196 }
00197 
00198 void MaximGap::setConnectionHandle(uint16_t connectionHandle)
00199 {
00200     m_connectionHandle = connectionHandle;
00201 }
00202 
00203 uint16_t MaximGap::getConnectionHandle(void)
00204 {
00205     return m_connectionHandle;
00206 }
00207 
00208 ble_error_t MaximGap::setAddress(AddressType_t type, const Address_t address)
00209 {
00210     if ((type != BLEProtocol::AddressType::PUBLIC) && (type != BLEProtocol::AddressType::RANDOM_STATIC)) {
00211         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00212     }
00213 
00214     m_type = type;
00215     HciVsSetPublicAddr((uint8_t*)address);
00216 
00217     return BLE_ERROR_NONE;
00218 }
00219 
00220 ble_error_t MaximGap::getAddress(AddressType_t *typeP, Address_t address)
00221 {
00222     *typeP = m_type;
00223     BdaCpy(address, HciGetBdAddr ());
00224     return BLE_ERROR_NONE;
00225 }
00226 
00227 ble_error_t MaximGap::setDeviceName(const uint8_t *deviceName)
00228 {
00229     return BLE_ERROR_NOT_IMPLEMENTED;
00230 }
00231 
00232 ble_error_t MaximGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
00233 {
00234     return BLE_ERROR_NOT_IMPLEMENTED;
00235 }
00236 
00237 ble_error_t MaximGap::setAppearance(GapAdvertisingData::Appearance appearance)
00238 {
00239     return BLE_ERROR_NOT_IMPLEMENTED;
00240 }
00241 
00242 ble_error_t MaximGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
00243 {
00244     return BLE_ERROR_NOT_IMPLEMENTED;
00245 }
00246 
00247 ble_error_t MaximGap::setTxPower(int8_t txPower)
00248 {
00249     HciVsSetTxPower(txPower);
00250     return BLE_ERROR_NONE;
00251 }
00252 
00253 void MaximGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP)
00254 {
00255     static const int8_t permittedTxValues[] = {
00256         -18, -15, -12, -9, -6, -3, 0, 3
00257     };
00258 
00259     *valueArrayPP = permittedTxValues;
00260     *countP = sizeof(permittedTxValues) / sizeof(int8_t);
00261 }