My fork of X_NUCLEO_IDB0XA1

Fork of X_NUCLEO_IDB0XA1 by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BlueNRGGap.cpp Source File

BlueNRGGap.cpp

Go to the documentation of this file.
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 
00018 /**
00019   ******************************************************************************
00020   * @file    BlueNRGGap.cpp
00021   * @author  STMicroelectronics
00022   * @brief   Implementation of BLE_API Gap Class
00023   ******************************************************************************
00024   * @copy
00025   *
00026   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00027   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
00028   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
00029   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00030   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00031   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00032   *
00033   * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
00034   */
00035 
00036 /** @defgroup BlueNRGGap
00037  *  @brief BlueNRG BLE_API GAP Adaptation
00038  *  @{
00039  */
00040 
00041 #include "BlueNRGDevice.h"
00042 #ifdef YOTTA_CFG_MBED_OS
00043     #include "mbed-drivers/mbed.h"
00044 #else
00045     #include "mbed.h"
00046 #endif
00047 #include "ble_payload.h"
00048 #include "ble_utils.h"
00049 #include "ble_debug.h"
00050 
00051 /*
00052  * Utility to process GAP specific events (e.g., Advertising timeout)
00053  */
00054 void BlueNRGGap::Process(void)
00055 {
00056     if(AdvToFlag) {
00057         stopAdvertising();
00058     }
00059 
00060 }
00061 
00062 /**************************************************************************/
00063 /*!
00064     @brief  Sets the advertising parameters and payload for the device.
00065             Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API
00066 
00067     @params[in] advData
00068                 The primary advertising data payload
00069     @params[in] scanResponse
00070                 The optional Scan Response payload if the advertising
00071                 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
00072                 in \ref GapAdveritinngParams
00073 
00074     @returns    \ref ble_error_t
00075 
00076     @retval     BLE_ERROR_NONE
00077                 Everything executed properly
00078 
00079     @retval     BLE_ERROR_BUFFER_OVERFLOW
00080                 The proposed action would cause a buffer overflow.  All
00081                 advertising payloads must be <= 31 bytes, for example.
00082 
00083     @retval     BLE_ERROR_NOT_IMPLEMENTED
00084                 A feature was requested that is not yet supported in the
00085                 nRF51 firmware or hardware.
00086 
00087     @retval     BLE_ERROR_PARAM_OUT_OF_RANGE
00088                 One of the proposed values is outside the valid range.
00089 
00090     @section EXAMPLE
00091 
00092     @code
00093 
00094     @endcode
00095 */
00096 /**************************************************************************/
00097 ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
00098 {
00099     PRINTF("BlueNRGGap::setAdvertisingData\n\r");
00100     /* Make sure we don't exceed the advertising payload length */
00101     if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
00102         PRINTF("Exceeded the advertising payload length\n\r");
00103         return BLE_ERROR_BUFFER_OVERFLOW;
00104     }
00105 
00106     /* Make sure we have a payload! */
00107     if (advData.getPayloadLen() != 0) {
00108         PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());
00109 
00110         /* Align the GAP Service Appearance Char value coherently
00111            This setting is duplicate (see below GapAdvertisingData::APPEARANCE)
00112            since BLE API has an overloaded function for appearance
00113         */
00114         STORE_LE_16(deviceAppearance, advData.getAppearance());
00115         setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]));
00116 
00117 
00118         for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) {
00119             loadPtr.getUnitAtIndex(index);
00120 
00121             PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr()));
00122             PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()));
00123 
00124             switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) {
00125             /**< TX Power Level (in dBm) */
00126             case GapAdvertisingData::TX_POWER_LEVEL:
00127                 {
00128                 PRINTF("Advertising type: TX_POWER_LEVEL\n\r");
00129                 int8_t enHighPower = 0;
00130                 int8_t paLevel = 0;
00131 
00132                 int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr();
00133                 tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel);
00134 #ifdef DEBUG
00135                 PRINTF("dbm=%d, ret=%d\n\r", dbm, ret);
00136                 PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);
00137 #endif
00138                 if(ret == BLE_STATUS_SUCCESS) {
00139                   aci_hal_set_tx_power_level(enHighPower, paLevel);
00140                 }
00141                 break;
00142                 }
00143             /**< Appearance */
00144             case GapAdvertisingData::APPEARANCE:
00145                 {
00146                 PRINTF("Advertising type: APPEARANCE\n\r");
00147 
00148                 GapAdvertisingData::Appearance appearanceP;
00149                 memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2);
00150 
00151                 PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]);
00152 
00153                 appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]);
00154                 /* Align the GAP Service Appearance Char value coherently */
00155                 setAppearance(appearanceP);
00156                 break;
00157                 }
00158 
00159             } // end switch
00160 
00161         } //end for
00162 
00163     }
00164 
00165     // update the advertising data in the shield if advertising is running
00166     if (state.advertising == 1) {
00167         tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload());
00168 
00169         if(BLE_STATUS_SUCCESS != ret) {
00170             PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
00171             switch (ret) {
00172                 case BLE_STATUS_TIMEOUT:
00173                     return BLE_STACK_BUSY;
00174                 default:
00175                     return BLE_ERROR_UNSPECIFIED;
00176             }
00177         }
00178 
00179         ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload());
00180         if (ret) {
00181             PRINTF("error while setting the payload\r\n");
00182             return BLE_ERROR_UNSPECIFIED;
00183         }
00184     }
00185 
00186     _advData = advData;
00187     _scanResponse = scanResponse;
00188 
00189     return BLE_ERROR_NONE;
00190 }
00191 
00192 /*
00193  * Utility to set ADV timeout flag
00194  */
00195 void BlueNRGGap::setAdvToFlag(void) {
00196     AdvToFlag = true;
00197 }
00198 
00199 /*
00200  * ADV timeout callback
00201  */
00202 #ifdef AST_FOR_MBED_OS
00203 static void advTimeoutCB(void)
00204 {
00205     Gap::GapState_t state;
00206 
00207     state = BlueNRGGap::getInstance().getState();
00208     if (state.advertising == 1) {
00209 
00210         BlueNRGGap::getInstance().stopAdvertising();
00211 
00212     }
00213 }
00214 #else
00215 static void advTimeoutCB(void)
00216 {
00217     Gap::GapState_t state;
00218 
00219     state = BlueNRGGap::getInstance().getState();
00220     if (state.advertising == 1) {
00221 
00222         BlueNRGGap::getInstance().setAdvToFlag();
00223 
00224         Timeout t = BlueNRGGap::getInstance().getAdvTimeout();
00225         t.detach(); /* disable the callback from the timeout */
00226 
00227     }
00228 }
00229 #endif /* AST_FOR_MBED_OS */
00230 
00231 /**************************************************************************/
00232 /*!
00233     @brief  Starts the BLE HW, initialising any services that were
00234             added before this function was called.
00235 
00236     @param[in]  params
00237                 Basic advertising details, including the advertising
00238                 delay, timeout and how the device should be advertised
00239 
00240     @note   All services must be added before calling this function!
00241 
00242     @returns    ble_error_t
00243 
00244     @retval     BLE_ERROR_NONE
00245                 Everything executed properly
00246 
00247     @section EXAMPLE
00248 
00249     @code
00250 
00251     @endcode
00252 */
00253 /**************************************************************************/
00254 
00255 ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams &params)
00256 {
00257     tBleStatus ret;
00258     int err;
00259 
00260     /* Make sure we support the advertising type */
00261     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
00262         /* ToDo: This requires a proper security implementation, etc. */
00263         return BLE_ERROR_NOT_IMPLEMENTED;
00264     }
00265 
00266     /* Check interval range */
00267     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
00268         /* Min delay is slightly longer for unconnectable devices */
00269         if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
00270                 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
00271             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00272         }
00273     } else {
00274         if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
00275                 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
00276             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00277         }
00278     }
00279 
00280     /* Check timeout is zero for Connectable Directed */
00281     if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
00282         /* Timeout must be 0 with this type, although we'll never get here */
00283         /* since this isn't implemented yet anyway */
00284         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00285     }
00286 
00287     /* Check timeout for other advertising types */
00288     if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
00289             (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
00290         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00291     }
00292 
00293     /*
00294      * Advertising filter policy setting
00295      * FIXME: the Security Manager should be implemented
00296      */
00297     AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode();
00298     if(mode != ADV_POLICY_IGNORE_WHITELIST) {
00299         ret = aci_gap_configure_whitelist();
00300         if(ret != BLE_STATUS_SUCCESS) {
00301           PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret);
00302           return BLE_ERROR_OPERATION_NOT_PERMITTED;
00303         }
00304     }
00305 
00306     uint8_t advFilterPolicy = NO_WHITE_LIST_USE;
00307     switch(mode) {
00308         case ADV_POLICY_FILTER_SCAN_REQS:
00309             advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN;
00310             break;
00311         case ADV_POLICY_FILTER_CONN_REQS:
00312             advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN;
00313             break;
00314         case ADV_POLICY_FILTER_ALL_REQS:
00315             advFilterPolicy = WHITE_LIST_FOR_ALL;
00316             break;
00317         default:
00318             advFilterPolicy = NO_WHITE_LIST_USE;
00319             break;
00320     }
00321 
00322     /* Check the ADV type before setting scan response data */
00323     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED ||
00324         params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) {
00325 
00326         /* set scan response data */
00327         PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen());
00328         ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload());
00329 
00330         if(BLE_STATUS_SUCCESS!=ret) {
00331             PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
00332             switch (ret) {
00333               case BLE_STATUS_TIMEOUT:
00334                 return BLE_STACK_BUSY;
00335               default:
00336                 return BLE_ERROR_UNSPECIFIED;
00337             }
00338         }
00339     } else {
00340         hci_le_set_scan_resp_data(0, NULL);
00341     }
00342 
00343     setAdvParameters();
00344     PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType());
00345 
00346     err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload());
00347 
00348     if (err) {
00349         PRINTF("error while setting the payload\r\n");
00350         return BLE_ERROR_UNSPECIFIED;
00351     }
00352 
00353     tBDAddr dummy_addr = { 0 };
00354     uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval;
00355     uint16_t advIntervalMax = advIntervalMin + 1;
00356 
00357     err = hci_le_set_advertising_parameters(
00358         advIntervalMin,
00359         advIntervalMax,
00360         params.getAdvertisingType(),
00361         addr_type,
00362         0x00,
00363         dummy_addr,
00364         /* all channels */ 7,
00365         advFilterPolicy
00366     );
00367 
00368     if (err) {
00369         PRINTF("impossible to set advertising parameters\n\r");
00370         PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1);
00371         PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy);
00372         return BLE_ERROR_INVALID_PARAM;
00373     }
00374 
00375     err = hci_le_set_advertise_enable(0x01);
00376     if (err) {
00377         PRINTF("impossible to start advertising\n\r");
00378         return BLE_ERROR_UNSPECIFIED;
00379     }
00380 
00381     state.advertising = 1;
00382 
00383     AdvToFlag = false;
00384     if(params.getTimeout() != 0) {
00385         PRINTF("!!! attaching to!!!\n");
00386 #ifdef AST_FOR_MBED_OS
00387         minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000));
00388 #else
00389         advTimeout.attach(advTimeoutCB, params.getTimeout() * 1000);
00390 #endif
00391     }
00392 
00393     return BLE_ERROR_NONE;
00394 
00395 }
00396 
00397 
00398 /**************************************************************************/
00399 /*!
00400     @brief  Stops the BLE HW and disconnects from any devices
00401 
00402     @returns    ble_error_t
00403 
00404     @retval     BLE_ERROR_NONE
00405                 Everything executed properly
00406 
00407     @section EXAMPLE
00408 
00409     @code
00410 
00411     @endcode
00412 */
00413 /**************************************************************************/
00414 ble_error_t BlueNRGGap::stopAdvertising(void)
00415 {
00416 
00417     if(state.advertising == 1) {
00418 
00419         int err = hci_le_set_advertise_enable(0);
00420         if (err) {
00421             return BLE_ERROR_OPERATION_NOT_PERMITTED;
00422         }
00423 
00424         PRINTF("Advertisement stopped!!\n\r") ;
00425         //Set GapState_t::advertising state
00426         state.advertising = 0;
00427     }
00428 
00429     return BLE_ERROR_NONE;
00430 }
00431 
00432 /**************************************************************************/
00433 /*!
00434     @brief  Disconnects if we are connected to a central device
00435 
00436     @param[in]  reason
00437                 Disconnection Reason
00438 
00439     @returns    ble_error_t
00440 
00441     @retval     BLE_ERROR_NONE
00442                 Everything executed properly
00443 
00444     @section EXAMPLE
00445 
00446     @code
00447 
00448     @endcode
00449 */
00450 /**************************************************************************/
00451 ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason)
00452 {
00453     tBleStatus ret;
00454 
00455     ret = aci_gap_terminate(connectionHandle, reason);
00456 
00457     if (BLE_STATUS_SUCCESS != ret){
00458         PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
00459         switch (ret) {
00460           case ERR_COMMAND_DISALLOWED:
00461             return BLE_ERROR_OPERATION_NOT_PERMITTED;
00462           case BLE_STATUS_TIMEOUT:
00463             return BLE_STACK_BUSY;
00464           default:
00465             return BLE_ERROR_UNSPECIFIED;
00466         }
00467     }
00468 
00469     return BLE_ERROR_NONE;
00470 }
00471 
00472 /**************************************************************************/
00473 /*!
00474     @brief  Disconnects if we are connected to a central device
00475 
00476     @param[in]  reason
00477                 Disconnection Reason
00478 
00479     @returns    ble_error_t
00480 
00481     @retval     BLE_ERROR_NONE
00482                 Everything executed properly
00483 
00484     @section EXAMPLE
00485 
00486     @code
00487 
00488     @endcode
00489 */
00490 /**************************************************************************/
00491 ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason)
00492 {
00493     return disconnect(m_connectionHandle, reason);
00494 }
00495 
00496 /**************************************************************************/
00497 /*!
00498     @brief  Sets the 16-bit connection handle
00499 
00500     @param[in]  conn_handle
00501                 Connection Handle which is set in the Gap Instance
00502 
00503     @returns    void
00504 */
00505 /**************************************************************************/
00506 void BlueNRGGap::setConnectionHandle(uint16_t conn_handle)
00507 {
00508     m_connectionHandle = conn_handle;
00509 }
00510 
00511 /**************************************************************************/
00512 /*!
00513     @brief  Gets the 16-bit connection handle
00514 
00515     @param[in]  void
00516 
00517     @returns    uint16_t
00518                 Connection Handle of the Gap Instance
00519 */
00520 /**************************************************************************/
00521 uint16_t BlueNRGGap::getConnectionHandle(void)
00522 {
00523     return m_connectionHandle;
00524 }
00525 
00526 /**************************************************************************/
00527 /*!
00528     @brief      Sets the BLE device address. SetAddress will reset the BLE
00529                 device and re-initialize BTLE. Will not start advertising.
00530 
00531     @param[in]  type
00532                 Type of Address
00533 
00534     @param[in]  address[6]
00535                 Value of the Address to be set
00536 
00537     @returns    ble_error_t
00538 
00539     @section EXAMPLE
00540 
00541     @code
00542 
00543     @endcode
00544 */
00545 /**************************************************************************/
00546 ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address)
00547 {
00548     if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
00549         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00550     }
00551 
00552     if(type == BLEProtocol::AddressType::PUBLIC){
00553         tBleStatus ret = aci_hal_write_config_data(
00554             CONFIG_DATA_PUBADDR_OFFSET,
00555             CONFIG_DATA_PUBADDR_LEN,
00556             address
00557         );
00558         if(ret != BLE_STATUS_SUCCESS) {
00559             return BLE_ERROR_OPERATION_NOT_PERMITTED;
00560         }
00561     } else if  (type == BLEProtocol::AddressType::RANDOM_STATIC) {
00562         // ensure that the random static address is well formed
00563         if ((address[5] & 0xC0) != 0xC0) {
00564             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00565         }
00566 
00567         // thanks to const correctness of the API ...
00568         tBDAddr random_address = { 0 };
00569         memcpy(random_address, address, sizeof(random_address));
00570         int err = hci_le_set_random_address(random_address);
00571         if (err) {
00572             return BLE_ERROR_OPERATION_NOT_PERMITTED;
00573         }
00574 
00575         // It is not possible to get the bluetooth address when it is set
00576         // store it locally in class data member
00577         memcpy(bdaddr, address, sizeof(bdaddr));
00578     } else {
00579         // FIXME random addresses are not supported yet
00580         // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE
00581         // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE
00582         return BLE_ERROR_NOT_IMPLEMENTED;
00583     }
00584 
00585     // if we're here then the address was correctly set
00586     // commit it inside the addr_type
00587     addr_type = type;
00588     isSetAddress = true;
00589     return BLE_ERROR_NONE;
00590 }
00591 
00592 /**************************************************************************/
00593 /*!
00594     @brief      Returns boolean if the address of the device has been set
00595                 or not
00596 
00597     @returns    bool
00598 
00599     @section EXAMPLE
00600 
00601     @code
00602 
00603     @endcode
00604 */
00605 /**************************************************************************/
00606 bool BlueNRGGap::getIsSetAddress()
00607 {
00608     return isSetAddress;
00609 }
00610 
00611 /**************************************************************************/
00612 /*!
00613     @brief      Returns the address of the device if set
00614 
00615     @returns    Pointer to the address if Address is set else NULL
00616 
00617     @section EXAMPLE
00618 
00619     @code
00620 
00621     @endcode
00622 */
00623 /**************************************************************************/
00624 ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address)
00625 {
00626     uint8_t bdaddr[BDADDR_SIZE];
00627     uint8_t data_len_out;
00628 
00629     // precondition, check that pointers in input are valid
00630     if (typeP == NULL || address == NULL) {
00631         return BLE_ERROR_INVALID_PARAM;
00632     }
00633 
00634     if (addr_type == BLEProtocol::AddressType::PUBLIC) {
00635         tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr);
00636         if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) {
00637             return BLE_ERROR_UNSPECIFIED;
00638         }
00639     } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) {
00640         // FIXME hci_read_bd_addr and
00641         // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1
00642         // does not work, use the address stored in class data member
00643         memcpy(bdaddr, this->bdaddr, sizeof(bdaddr));
00644     } else {
00645         // FIXME: should be implemented with privacy features
00646         // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE
00647         // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE
00648         return BLE_ERROR_NOT_IMPLEMENTED;
00649     }
00650 
00651     *typeP = addr_type;
00652     memcpy(address, bdaddr, BDADDR_SIZE);
00653 
00654     return BLE_ERROR_NONE;
00655 }
00656 
00657 /**************************************************************************/
00658 /*!
00659     @brief      obtains preferred connection params
00660 
00661     @returns    ble_error_t
00662 
00663     @section EXAMPLE
00664 
00665     @code
00666 
00667     @endcode
00668 */
00669 /**************************************************************************/
00670 ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params)
00671 {
00672     static const size_t parameter_size = 2;
00673 
00674     if (!g_preferred_connection_parameters_char_handle) {
00675         return BLE_ERROR_OPERATION_NOT_PERMITTED;
00676     }
00677 
00678     // Peripheral preferred connection parameters are an array of 4 uint16_t
00679     uint8_t parameters_packed[parameter_size * 4];
00680     uint16_t bytes_read = 0;
00681 
00682     tBleStatus err = aci_gatt_read_handle_value(
00683         g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE,
00684         sizeof(parameters_packed),
00685         &bytes_read,
00686         parameters_packed
00687     );
00688 
00689     PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read);
00690 
00691     // check that the read succeed and the result have the expected length
00692     if (err || bytes_read != sizeof(parameters_packed)) {
00693         return BLE_ERROR_UNSPECIFIED;
00694     }
00695 
00696     // memcpy field by field
00697     memcpy(&params->minConnectionInterval, parameters_packed, parameter_size);
00698     memcpy(&params->maxConnectionInterval, &parameters_packed[parameter_size], parameter_size);
00699     memcpy(&params->slaveLatency, &parameters_packed[2 * parameter_size], parameter_size);
00700     memcpy(&params->connectionSupervisionTimeout, &parameters_packed[3 * parameter_size], parameter_size);
00701 
00702     return BLE_ERROR_NONE;
00703 }
00704 
00705 
00706 /**************************************************************************/
00707 /*!
00708     @brief      sets preferred connection params
00709 
00710     @returns    ble_error_t
00711 
00712     @section EXAMPLE
00713 
00714     @code
00715 
00716     @endcode
00717 */
00718 /**************************************************************************/
00719 ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params)
00720 {
00721     static const size_t parameter_size = 2;
00722     uint8_t parameters_packed[parameter_size * 4];
00723 
00724     // ensure that parameters are correct
00725     // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C]
00726     // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC
00727     if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) &&
00728         params->minConnectionInterval != 0xFFFF) {
00729         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00730     }
00731 
00732     if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) &&
00733         params->maxConnectionInterval != 0xFFFF) {
00734         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00735     }
00736 
00737     if (params->slaveLatency > 0x01F3) {
00738         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00739     }
00740 
00741     if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) &&
00742         params->connectionSupervisionTimeout != 0xFFFF) {
00743         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00744     }
00745 
00746     // copy the parameters inside the byte array
00747     memcpy(parameters_packed, &params->minConnectionInterval, parameter_size);
00748     memcpy(&parameters_packed[parameter_size], &params->maxConnectionInterval, parameter_size);
00749     memcpy(&parameters_packed[2 * parameter_size], &params->slaveLatency, parameter_size);
00750     memcpy(&parameters_packed[3 * parameter_size], &params->connectionSupervisionTimeout, parameter_size);
00751 
00752     tBleStatus err = aci_gatt_update_char_value(
00753         g_gap_service_handle,
00754         g_preferred_connection_parameters_char_handle,
00755         /* offset */ 0,
00756         sizeof(parameters_packed),
00757         parameters_packed
00758     );
00759 
00760     if (err) {
00761         PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ;
00762         switch (err) {
00763           case BLE_STATUS_INVALID_HANDLE:
00764           case BLE_STATUS_INVALID_PARAMETER:
00765             return BLE_ERROR_INVALID_PARAM;
00766           case BLE_STATUS_INSUFFICIENT_RESOURCES:
00767             return BLE_ERROR_NO_MEM;
00768           case BLE_STATUS_TIMEOUT:
00769             return BLE_STACK_BUSY;
00770           default:
00771             return BLE_ERROR_UNSPECIFIED;
00772         }
00773     }
00774 
00775     return BLE_ERROR_NONE;
00776 }
00777 
00778 /**************************************************************************/
00779 /*!
00780     @brief      updates preferred connection params
00781 
00782     @returns    ble_error_t
00783 
00784     @section EXAMPLE
00785 
00786     @code
00787 
00788     @endcode
00789 */
00790 /**************************************************************************/
00791 ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params)
00792 {
00793     tBleStatus ret = BLE_STATUS_SUCCESS;
00794 
00795     if(gapRole == Gap::CENTRAL) {
00796         ret = aci_gap_start_connection_update(handle,
00797                                               params->minConnectionInterval,
00798                                               params->maxConnectionInterval,
00799                                               params->slaveLatency,
00800                                               params->connectionSupervisionTimeout,
00801                                               CONN_L1, CONN_L2);
00802     } else {
00803         ret = aci_l2cap_connection_parameter_update_request(handle,
00804                                                             params->minConnectionInterval,
00805                                                             params->maxConnectionInterval,
00806                                                             params->slaveLatency,
00807                                                             params->connectionSupervisionTimeout);
00808     }
00809 
00810     if (BLE_STATUS_SUCCESS != ret){
00811         PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ;
00812         switch (ret) {
00813           case ERR_INVALID_HCI_CMD_PARAMS:
00814           case BLE_STATUS_INVALID_PARAMETER:
00815             return BLE_ERROR_INVALID_PARAM;
00816           case ERR_COMMAND_DISALLOWED:
00817           case BLE_STATUS_NOT_ALLOWED:
00818             return BLE_ERROR_OPERATION_NOT_PERMITTED;
00819           default:
00820             return BLE_ERROR_UNSPECIFIED;
00821         }
00822     }
00823 
00824     return BLE_ERROR_NONE;
00825 }
00826 
00827 /**************************************************************************/
00828 /*!
00829     @brief  Sets the Device Name Characteristic
00830 
00831     @param[in]  deviceName
00832                 pointer to device name to be set
00833 
00834     @returns    ble_error_t
00835 
00836     @retval     BLE_ERROR_NONE
00837                 Everything executed properly
00838 
00839     @section EXAMPLE
00840 
00841     @code
00842 
00843     @endcode
00844 */
00845 /**************************************************************************/
00846 ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName)
00847 {
00848     tBleStatus ret;
00849     uint8_t nameLen = 0;
00850 
00851     nameLen = strlen((const char*)deviceName);
00852     PRINTF("DeviceName Size=%d\n\r", nameLen);
00853 
00854     ret = aci_gatt_update_char_value(g_gap_service_handle,
00855                                      g_device_name_char_handle,
00856                                      0,
00857                                      nameLen,
00858                                      deviceName);
00859 
00860     if (BLE_STATUS_SUCCESS != ret){
00861         PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ;
00862         switch (ret) {
00863           case BLE_STATUS_INVALID_HANDLE:
00864           case BLE_STATUS_INVALID_PARAMETER:
00865             return BLE_ERROR_INVALID_PARAM;
00866           case BLE_STATUS_INSUFFICIENT_RESOURCES:
00867             return BLE_ERROR_NO_MEM;
00868           case BLE_STATUS_TIMEOUT:
00869             return BLE_STACK_BUSY;
00870           default:
00871             return BLE_ERROR_UNSPECIFIED;
00872         }
00873     }
00874 
00875     return BLE_ERROR_NONE;
00876 }
00877 
00878 /**************************************************************************/
00879 /*!
00880     @brief  Gets the Device Name Characteristic
00881 
00882     @param[in]  deviceName
00883                 pointer to device name
00884 
00885     @param[in]  lengthP
00886                 pointer to device name length
00887 
00888     @returns    ble_error_t
00889 
00890     @retval     BLE_ERROR_NONE
00891                 Everything executed properly
00892 
00893     @section EXAMPLE
00894 
00895     @code
00896 
00897     @endcode
00898 */
00899 /**************************************************************************/
00900 ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
00901 {
00902     tBleStatus ret;
00903 
00904     ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
00905                                      *lengthP,
00906                                      (uint16_t *)lengthP,
00907                                      deviceName);
00908     PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP);
00909     if (ret == BLE_STATUS_SUCCESS) {
00910         return BLE_ERROR_NONE;
00911     } else {
00912         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00913     }
00914 }
00915 
00916 /**************************************************************************/
00917 /*!
00918     @brief  Sets the Device Appearance Characteristic
00919 
00920     @param[in]  appearance
00921                 device appearance
00922 
00923     @returns    ble_error_t
00924 
00925     @retval     BLE_ERROR_NONE
00926                 Everything executed properly
00927 
00928     @section EXAMPLE
00929 
00930     @code
00931 
00932     @endcode
00933 */
00934 /**************************************************************************/
00935 ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance)
00936 {
00937     tBleStatus ret;
00938     uint8_t deviceAppearance[2];
00939 
00940     STORE_LE_16(deviceAppearance, appearance);
00941     PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]);
00942 
00943     ret = aci_gatt_update_char_value(g_gap_service_handle,
00944                                      g_appearance_char_handle,
00945                                      0, 2, (uint8_t *)deviceAppearance);
00946     if (BLE_STATUS_SUCCESS == ret){
00947         return BLE_ERROR_NONE;
00948     }
00949 
00950     PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret);
00951     switch (ret) {
00952       case BLE_STATUS_INVALID_HANDLE:
00953       case BLE_STATUS_INVALID_PARAMETER:
00954         return BLE_ERROR_INVALID_PARAM;
00955       case BLE_STATUS_INSUFFICIENT_RESOURCES:
00956         return BLE_ERROR_NO_MEM;
00957       case BLE_STATUS_TIMEOUT:
00958         return BLE_STACK_BUSY;
00959       default:
00960         return BLE_ERROR_UNSPECIFIED;
00961     }
00962 }
00963 
00964 /**************************************************************************/
00965 /*!
00966     @brief  Gets the Device Appearance Characteristic
00967 
00968     @param[in]  appearance
00969                 pointer to device appearance value
00970 
00971     @returns    ble_error_t
00972 
00973     @retval     BLE_ERROR_NONE
00974                 Everything executed properly
00975 
00976     @section EXAMPLE
00977 
00978     @code
00979 
00980     @endcode
00981 */
00982 /**************************************************************************/
00983 ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
00984 {
00985     tBleStatus ret;
00986     uint16_t lengthP = 2;
00987 
00988     ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
00989                                      lengthP,
00990                                      &lengthP,
00991                                      (uint8_t*)appearanceP);
00992     PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP);
00993     if (ret == BLE_STATUS_SUCCESS) {
00994         return BLE_ERROR_NONE;
00995     } else {
00996         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00997     }
00998 
00999 }
01000 
01001 GapScanningParams* BlueNRGGap::getScanningParams(void)
01002 {
01003   return &_scanningParams;
01004 }
01005 
01006 static void makeConnection(void)
01007 {
01008   BlueNRGGap::getInstance().createConnection();
01009 }
01010 
01011 void BlueNRGGap::Discovery_CB(Reason_t reason,
01012                               uint8_t adv_type,
01013                               uint8_t addr_type,
01014                               uint8_t *addr,
01015                               uint8_t *data_length,
01016                               uint8_t *data,
01017                               uint8_t *RSSI)
01018 {
01019   switch (reason) {
01020   case DEVICE_FOUND:
01021     {
01022       GapAdvertisingParams::AdvertisingType_t type;
01023       bool isScanResponse = false;
01024 
01025       /*
01026        * Whitelisting (scan policy):
01027        * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) &&
01028        * Private Random Address
01029        * => scan_results = FALSE
01030        * FIXME: the Security Manager should be implemented
01031        */
01032       ScanningPolicyMode_t mode = getScanningPolicyMode();
01033       PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type);
01034       if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV ||
01035          (addr_type == RESOLVABLE_PRIVATE_ADDR ||
01036           addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) {
01037         return;
01038       }
01039 
01040       switch(adv_type) {
01041       case ADV_IND:
01042         type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
01043         break;
01044       case ADV_DIRECT_IND:
01045         type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED;
01046         break;
01047       case ADV_SCAN_IND:
01048       case SCAN_RSP:
01049         type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED;
01050         isScanResponse = true;
01051         break;
01052       case ADV_NONCONN_IND:
01053         type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED;
01054         break;
01055       default:
01056         type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
01057       }
01058 
01059       PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n",
01060              *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
01061       if(!_connecting) {
01062         processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data);
01063       }
01064       PRINTF("!!!After processAdvertisementReport\n\r");
01065     }
01066     break;
01067 
01068   case DISCOVERY_COMPLETE:
01069     // The discovery is complete. If this is due to a stop scanning (i.e., the device
01070     // we are interested in has been found) and a connection has been requested
01071     // then we start the device connection.
01072     PRINTF("DISCOVERY_COMPLETE\n\r");
01073     _scanning = false;
01074 
01075     // Since the DISCOVERY_COMPLETE event can be received during the scanning interval,
01076     // we need to delay the starting of connection
01077     uint16_t delay = 2*(_scanningParams.getInterval());
01078 
01079 #ifdef AST_FOR_MBED_OS
01080     if(_connecting) {
01081       minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay));
01082     }
01083 #else
01084     Clock_Wait(delay);
01085     if(_connecting) {
01086       makeConnection();
01087     }
01088 #endif /* AST_FOR_MBED_OS */
01089 
01090     break;
01091   }
01092 }
01093 
01094 ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams)
01095 {
01096 
01097   tBleStatus ret = BLE_STATUS_SUCCESS;
01098 
01099   // Stop ADV before scanning
01100   /*
01101   if (state.advertising == 1) {
01102     stopAdvertising();
01103   }
01104   */
01105 
01106   /*
01107    * Whitelisting (scan policy):
01108    * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) &&
01109    * White List is empty
01110    * => scan operation = FAILURE
01111    * FIXME: the Security Manager should be implemented
01112    */
01113   ScanningPolicyMode_t mode = getScanningPolicyMode();
01114   uint8_t whiteListSize = whitelistAddresses.size;
01115   if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) {
01116     return BLE_ERROR_OPERATION_NOT_PERMITTED;
01117   }
01118 
01119   ret = btleStartRadioScan(scanningParams.getActiveScanning(),
01120                            scanningParams.getInterval(),
01121                            scanningParams.getWindow(),
01122                            addr_type);
01123 
01124   PRINTF("Scanning...\n\r");
01125   PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000);
01126   PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000);
01127   //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval());
01128   //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1);
01129   //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2);
01130   if (BLE_STATUS_SUCCESS == ret){
01131     PRINTF("Observation Procedure Started\n");
01132     _scanning = true;
01133     return BLE_ERROR_NONE;
01134   }
01135 
01136   // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED
01137   switch (ret) {
01138     case BLE_STATUS_INVALID_CID:
01139       PRINTF("Observation Procedure not implemented!!!\n\r");
01140       return BLE_ERROR_NOT_IMPLEMENTED;
01141     default:
01142       PRINTF("Observation Procedure failed (0x%02X)\n\r", ret);
01143       return BLE_ERROR_UNSPECIFIED;
01144   }
01145 
01146 }
01147 
01148 ble_error_t BlueNRGGap::stopScan() {
01149   tBleStatus ret = BLE_STATUS_SUCCESS;
01150 
01151   PRINTF("stopScan\n\r");
01152   ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC);
01153 
01154   if (ret != BLE_STATUS_SUCCESS) {
01155     PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret);
01156     return BLE_ERROR_UNSPECIFIED;
01157   } else {
01158     PRINTF("Discovery Procedure Terminated\n");
01159     return BLE_ERROR_NONE;
01160   }
01161 }
01162 
01163 /**************************************************************************/
01164 /*!
01165     @brief  set Tx power level
01166     @param[in] txPower Transmission Power level
01167     @returns    ble_error_t
01168 */
01169 /**************************************************************************/
01170 ble_error_t BlueNRGGap::setTxPower(int8_t txPower)
01171 {
01172     tBleStatus ret;
01173 
01174     int8_t enHighPower = 0;
01175     int8_t paLevel = 0;
01176 
01177     ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel);
01178     if(ret!=BLE_STATUS_SUCCESS) {
01179         return BLE_ERROR_PARAM_OUT_OF_RANGE;
01180     }
01181 
01182     PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);
01183     ret = aci_hal_set_tx_power_level(enHighPower, paLevel);
01184     if(ret!=BLE_STATUS_SUCCESS) {
01185       return BLE_ERROR_PARAM_OUT_OF_RANGE;
01186     }
01187 
01188     return BLE_ERROR_NONE;
01189 }
01190 
01191 /**************************************************************************/
01192 /*!
01193     @brief  get permitted Tx power values
01194     @param[in] values pointer to pointer to permitted power values
01195     @param[in] num number of values
01196 */
01197 /**************************************************************************/
01198 void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
01199     static const int8_t permittedTxValues[] = {
01200         -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8
01201     };
01202 
01203     *valueArrayPP = permittedTxValues;
01204     *countP = sizeof(permittedTxValues) / sizeof(int8_t);
01205 }
01206 
01207 /**************************************************************************/
01208 /*!
01209     @brief  Set advertising parameters according to the current state
01210             Parameters value is set taking into account guidelines of the BlueNRG
01211             time slots allocation
01212 */
01213 /**************************************************************************/
01214 void BlueNRGGap::setAdvParameters(void)
01215 {
01216   uint32_t advIntMS;
01217 
01218   if(state.connected == 1) {
01219     advIntMS = (conn_min_interval*1.25)-GUARD_INT;
01220     advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS);
01221 
01222     PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval);
01223   } else {
01224     advInterval = _advParams.getIntervalInADVUnits();
01225   }
01226 }
01227 
01228 /**************************************************************************/
01229 /*!
01230     @brief  Set connection parameters according to the current state (ADV and/or SCAN)
01231             Parameters value is set taking into account guidelines of the BlueNRG
01232             time slots allocation
01233 */
01234 /**************************************************************************/
01235 void BlueNRGGap::setConnectionParameters(void)
01236 {
01237   if (state.advertising == 1) {
01238 
01239     if (_scanningParams.getInterval() < advInterval) {
01240       PRINTF("state.adv=1 scanInterval<advInterval\r\n");
01241       scanInterval = advInterval;
01242       scanWindow = advInterval;
01243     } else {
01244       PRINTF("state.adv=1 scanInterval>=advInterval\r\n");
01245       scanInterval = _scanningParams.getInterval();
01246       scanWindow = _scanningParams.getWindow();
01247     }
01248 
01249     if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms
01250         conn_min_interval = MAX_INT_CONN;
01251         conn_max_interval = MAX_INT_CONN;
01252     } else {
01253         conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25;
01254         conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25;
01255     }
01256 
01257   } else {
01258 
01259     PRINTF("state.adv = 0\r\n");
01260 
01261     scanInterval = _scanningParams.getInterval();
01262     scanWindow = _scanningParams.getWindow();
01263     if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) ||
01264        SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms
01265         conn_min_interval = DEF_INT_CONN;
01266         conn_max_interval = DEF_INT_CONN;
01267     } else {
01268         conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25;
01269         conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25;
01270     }
01271   }
01272   PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval));
01273   PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow));
01274   PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25));
01275   PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25));
01276 
01277 }
01278 
01279 ble_error_t BlueNRGGap::createConnection ()
01280 {
01281   tBleStatus ret;
01282 
01283   /*
01284      Before creating connection, set parameters according
01285      to previous or current procedure (ADV and/or SCAN)
01286    */
01287   setConnectionParameters();
01288 
01289   /*
01290     Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min,
01291     Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max
01292   */
01293   ret = aci_gap_create_connection(scanInterval,
01294                   scanWindow,
01295                   _peerAddrType,
01296                   (unsigned char*)_peerAddr,
01297                   addr_type,
01298                   conn_min_interval, conn_max_interval, 0,
01299                   SUPERV_TIMEOUT, CONN_L1, CONN_L1);
01300 
01301   //_connecting = false;
01302 
01303   if (ret != BLE_STATUS_SUCCESS) {
01304     PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret);
01305     return BLE_ERROR_UNSPECIFIED;
01306   } else {
01307     PRINTF("Connection started.\n");
01308     _connecting = false;
01309     return BLE_ERROR_NONE;
01310   }
01311 }
01312 
01313 ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr,
01314                                  Gap::AddressType_t peerAddrType,
01315                                  const ConnectionParams_t *connectionParams,
01316                                  const GapScanningParams *scanParams)
01317 {
01318   /* avoid compiler warnings about unused variables */
01319   (void)connectionParams;
01320 
01321   setScanParams(scanParams->getInterval(),
01322                 scanParams->getWindow(),
01323                 scanParams->getTimeout(),
01324                 scanParams->getActiveScanning()
01325                );
01326 
01327   // Save the peer address
01328   for(int i=0; i<BDADDR_SIZE; i++) {
01329     _peerAddr[i] = peerAddr[i];
01330   }
01331   _peerAddrType = peerAddrType;
01332 
01333   _connecting = true;
01334 
01335   if(_scanning) {
01336     stopScan();
01337   } else {
01338     PRINTF("Calling createConnection from connect()\n\r");
01339     return createConnection();
01340   }
01341 
01342   return BLE_ERROR_NONE;
01343 }
01344 
01345 /**************************************************************************/
01346 /*!
01347     @brief  Set the advertising policy filter mode that will be used in
01348             the next call to startAdvertising().
01349 
01350     @returns    \ref ble_errror_t
01351 
01352     @retval     BLE_ERROR_NONE
01353                 Everything executed properly.
01354 
01355                 BLE_ERROR_NOT_IMPLEMENTED
01356                 This feature is currently note implemented.
01357 */
01358 /**************************************************************************/
01359 ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode)
01360 {
01361    advertisingPolicyMode = mode;
01362 
01363     return BLE_ERROR_NONE;
01364 }
01365 
01366 /**************************************************************************/
01367 /*!
01368     @brief  Set the scanning policy filter mode that will be used in
01369             the next call to startAdvertising().
01370 
01371     @returns    \ref ble_errror_t
01372 
01373     @retval     BLE_ERROR_NONE
01374                 Everything executed properly.
01375 
01376                 BLE_ERROR_NOT_IMPLEMENTED
01377                 This feature is currently note implemented.
01378 */
01379 /**************************************************************************/
01380 ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode)
01381 {
01382     scanningPolicyMode = mode;
01383 
01384     return BLE_ERROR_NONE;
01385 }
01386 
01387 /**************************************************************************/
01388 /*!
01389     @brief  Get the current advertising policy filter mode.
01390 
01391     @returns    The advertising policy filter mode.
01392 */
01393 /**************************************************************************/
01394 Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const
01395 {
01396     return advertisingPolicyMode;
01397 }
01398 
01399 /**************************************************************************/
01400 /*!
01401     @brief  Get the current scanning policy filter mode.
01402 
01403     @returns    The scanning policy filter mode.
01404 
01405 */
01406 /**************************************************************************/
01407 Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const
01408 {
01409     return scanningPolicyMode;
01410 }
01411 
01412 /**************************************************************************/
01413 /*!
01414     @brief  Clear BlueNRGGap's state.
01415 
01416     @returns    ble_error_t
01417 
01418     @retval     BLE_ERROR_NONE
01419                 Everything executed properly
01420 */
01421 /**************************************************************************/
01422 ble_error_t BlueNRGGap::reset(void)
01423 {
01424     /* Clear all state that is from the parent, including private members */
01425     if (Gap::reset() != BLE_ERROR_NONE) {
01426         return BLE_ERROR_INVALID_STATE;
01427     }
01428 
01429     /* Clear derived class members */
01430     m_connectionHandle = BLE_CONN_HANDLE_INVALID;
01431 
01432     /* Set the whitelist policy filter modes to IGNORE_WHITELIST */
01433     advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST;
01434     scanningPolicyMode    = Gap::SCAN_POLICY_IGNORE_WHITELIST;
01435 
01436     return BLE_ERROR_NONE;
01437 }
01438 
01439 void BlueNRGGap::setConnectionInterval(uint16_t interval) {
01440     conn_min_interval = interval;
01441     conn_max_interval = interval;
01442 }
01443 
01444 void BlueNRGGap::setGapRole(Role_t role)
01445 {
01446     gapRole = role;
01447 }