Lorenzo Invidia / target_st_bluenrg

Dependents:   ble-star-mbed

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