Antonio Vilei / X_NUCLEO_IDB0XA1

Fork of X_NUCLEO_IDB0XA1 by ST Expansion SW Team

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