WILLIAN MATTOS / X_NUCLEO_IDB0XA1

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