project

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 // ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
00037 
00038 /** @defgroup BlueNRGGap
00039  *  @brief BlueNRG BLE_API GAP Adaptation
00040  *  @{
00041  */
00042 
00043 #include "BlueNRGDevice.h"
00044 #include "mbed.h"
00045 #include "Payload.h"
00046 #include "Utils.h"
00047 #include "debug.h"
00048 
00049 //Local Variables
00050 //const char *local_name = NULL;
00051 //uint8_t local_name_length = 0;
00052 const uint8_t *scan_response_payload = NULL;
00053 uint8_t scan_rsp_length = 0;
00054 
00055 uint32_t advtInterval = BLUENRG_GAP_ADV_INTERVAL_MAX;
00056 
00057 /*
00058  * Utility to process GAP specific events (e.g., Advertising timeout)
00059  */
00060 void BlueNRGGap::Process(void)
00061 {    
00062     if(AdvToFlag) {
00063         stopAdvertising();
00064     }
00065 
00066 }
00067 
00068 /**************************************************************************/
00069 /*!
00070     @brief  Sets the advertising parameters and payload for the device. 
00071             Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API
00072 
00073     @params[in] advData
00074                 The primary advertising data payload
00075     @params[in] scanResponse
00076                 The optional Scan Response payload if the advertising
00077                 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
00078                 in \ref GapAdveritinngParams
00079 
00080     @returns    \ref ble_error_t
00081 
00082     @retval     BLE_ERROR_NONE
00083                 Everything executed properly
00084 
00085     @retval     BLE_ERROR_BUFFER_OVERFLOW
00086                 The proposed action would cause a buffer overflow.  All
00087                 advertising payloads must be <= 31 bytes, for example.
00088 
00089     @retval     BLE_ERROR_NOT_IMPLEMENTED
00090                 A feature was requested that is not yet supported in the
00091                 nRF51 firmware or hardware.
00092 
00093     @retval     BLE_ERROR_PARAM_OUT_OF_RANGE
00094                 One of the proposed values is outside the valid range.
00095 
00096     @section EXAMPLE
00097 
00098     @code
00099 
00100     @endcode
00101 */
00102 /**************************************************************************/
00103 ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
00104 { 
00105     PRINTF("BlueNRGGap::setAdvertisingData\n\r");
00106     /* Make sure we don't exceed the advertising payload length */
00107     if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
00108         return BLE_ERROR_BUFFER_OVERFLOW;
00109     }
00110 
00111     /* Make sure we have a payload! */
00112     if (advData.getPayloadLen() <= 0) {
00113         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00114     } else { 
00115         PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());        
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", i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
00161                 }
00162 #endif /* DEBUG */
00163                 break;
00164                 }
00165             case GapAdvertisingData::INCOMPLETE_LIST_32BIT_SERVICE_IDS:  /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
00166                 {
00167                 PRINTF("Advertising type: INCOMPLETE_LIST_32BIT_SERVICE_IDS\n\r");
00168                 return BLE_ERROR_NOT_IMPLEMENTED;
00169                 }
00170             case GapAdvertisingData::COMPLETE_LIST_32BIT_SERVICE_IDS:    /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
00171                 {
00172                 PRINTF("Advertising type: COMPLETE_LIST_32BIT_SERVICE_IDS\n\r");
00173                 return BLE_ERROR_NOT_IMPLEMENTED;
00174                 }
00175             case GapAdvertisingData::SHORTENED_LOCAL_NAME:               /**< Shortened Local Name */
00176                 {
00177                 break;
00178                 }
00179             case GapAdvertisingData::COMPLETE_LOCAL_NAME:                /**< Complete Local Name */
00180                 {
00181                 PRINTF("Advertising type: COMPLETE_LOCAL_NAME\n\r");
00182                 loadPtr.getUnitAtIndex(index).printDataAsString();       
00183                 local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;                        
00184                 local_name = (uint8_t*)loadPtr.getUnitAtIndex(index).getAdTypePtr();
00185                 PRINTF("Advertising type: COMPLETE_LOCAL_NAME local_name=%s\n\r", local_name);
00186                 //COMPLETE_LOCAL_NAME is only advertising device name. Gatt Device Name is not the same.(Must be set right after GAP/GATT init?)
00187                 
00188                 PRINTF("device_name length=%d\n\r", local_name_length);                                    
00189                 break;
00190                 }
00191             case GapAdvertisingData::TX_POWER_LEVEL:                     /**< TX Power Level (in dBm) */
00192                 {
00193                 PRINTF("Advertising type: TX_POWER_LEVEL\n\r");     
00194                 int8_t enHighPower = 0;
00195                 int8_t paLevel = 0;
00196 #ifdef DEBUG
00197                 int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr();
00198                 int8_t dbmActuallySet = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel);
00199 #endif
00200                 PRINTF("dbm=%d, dbmActuallySet=%d\n\r", dbm, dbmActuallySet);
00201                 PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);                    
00202                 aci_hal_set_tx_power_level(enHighPower, paLevel);
00203                 break;
00204                 }
00205             case GapAdvertisingData::DEVICE_ID:                          /**< Device ID */
00206                 {
00207                 break;
00208                 }
00209             case GapAdvertisingData::SLAVE_CONNECTION_INTERVAL_RANGE:    /**< Slave :Connection Interval Range */
00210                 {
00211                 break;
00212                 }
00213             case GapAdvertisingData::SERVICE_DATA:                       /**< Service Data */
00214                 {
00215                 PRINTF("Advertising type: SERVICE_DATA\n\r");
00216                 uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;
00217                 PRINTF("Advertising type: SERVICE_DATA (buffSize=%d)\n\r", buffSize);
00218                 // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte
00219                 if(buffSize>ADV_DATA_MAX_SIZE-2) {
00220                     return BLE_ERROR_PARAM_OUT_OF_RANGE;
00221                 }
00222                 for(int i=0; i<buffSize+1; i++) {
00223                     PRINTF("Advertising type: SERVICE_DATA loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
00224                 }
00225                 AdvLen = buffSize+2; // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte
00226                 AdvData[0] = buffSize+1; // the fisrt byte is the data buffer size (type+data)
00227                 AdvData[1] = AD_TYPE_SERVICE_DATA;
00228                 memcpy(AdvData+2, loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize);
00229                 break;
00230                 }
00231             case GapAdvertisingData::APPEARANCE:   
00232                 {
00233                 /* 
00234                     Tested with GapAdvertisingData::GENERIC_PHONE. 
00235                     for other appearances BLE Scanner android app is not behaving properly 
00236                     */
00237                 PRINTF("Advertising type: APPEARANCE\n\r");
00238                 const char *deviceAppearance = NULL;                    
00239                 deviceAppearance = (const char*)loadPtr.getUnitAtIndex(index).getDataPtr();  // to be set later when startAdvertising() is called
00240                 
00241 #ifdef DEBUG
00242                 uint8_t Appearance[2] = {0, 0};
00243                 uint16_t devP = (uint16_t)*deviceAppearance;
00244                 STORE_LE_16(Appearance, (uint16_t)devP);
00245 #endif
00246                 
00247                 PRINTF("input: deviceAppearance= 0x%x 0x%x..., strlen(deviceAppearance)=%d\n\r", Appearance[1], Appearance[0], (uint8_t)*loadPtr.getUnitAtIndex(index).getLenPtr()-1);         /**< \ref Appearance */
00248                 
00249                 aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (uint8_t *)deviceAppearance);//not using array Appearance[2]
00250                 break;
00251                 }
00252             case GapAdvertisingData::ADVERTISING_INTERVAL:               /**< Advertising Interval */
00253                 {
00254                 PRINTF("Advertising type: ADVERTISING_INTERVAL\n\r");
00255                 advtInterval = (uint16_t)(*loadPtr.getUnitAtIndex(index).getDataPtr());
00256                 PRINTF("advtInterval=%d\n\r", (int)advtInterval);
00257                 break;
00258                 }
00259             case GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA:        /**< Manufacturer Specific Data */                             
00260                 {
00261                 PRINTF("Advertising type: MANUFACTURER_SPECIFIC_DATA\n\r");
00262                 uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;
00263                 PRINTF("Advertising type: MANUFACTURER_SPECIFIC_DATA (buffSize=%d)\n\r", buffSize);
00264                 // the total ADV DATA LEN should include two more bytes:
00265         // the buffer size byte;
00266         // and the Manufacturer Specific Data Type Value byte
00267                 if(buffSize>ADV_DATA_MAX_SIZE-2) {
00268                     return BLE_ERROR_PARAM_OUT_OF_RANGE;
00269                 }
00270                 for(int i=0; i<buffSize+1; i++) {
00271                     PRINTF("Advertising type: MANUFACTURER_SPECIFIC_DATA loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r",
00272                 i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
00273                 }
00274                 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
00275                 AdvData[0] = buffSize+1; // the fisrt byte is the data buffer size (type+data)
00276                 AdvData[1] = AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
00277                 memcpy(AdvData+2, loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize);
00278                 break;
00279                 }
00280                 
00281             }          
00282         }
00283         //Set the SCAN_RSP Payload
00284         scan_response_payload = scanResponse.getPayload();
00285         scan_rsp_length = scanResponse.getPayloadLen();
00286     }
00287     return BLE_ERROR_NONE;
00288 }
00289 
00290 /*
00291  * Utility to set ADV timeout flag
00292  */
00293 void BlueNRGGap::setAdvToFlag(void) {
00294     AdvToFlag = true;
00295 }
00296 
00297 /*
00298  * ADV timeout callback
00299  */   
00300 // ANDREA: mbedOS
00301 #ifdef AST_FOR_MBED_OS
00302 static void advTimeoutCB(void)
00303 {
00304     Gap::GapState_t state;
00305     
00306     state = BlueNRGGap::getInstance().getState();
00307     if (state.advertising == 1) {
00308         
00309         BlueNRGGap::getInstance().stopAdvertising();
00310         
00311     }
00312 }
00313 #else
00314 static void advTimeoutCB(void)
00315 {
00316     Gap::GapState_t state;
00317     
00318     state = BlueNRGGap::getInstance().getState();
00319     if (state.advertising == 1) {
00320         
00321         BlueNRGGap::getInstance().setAdvToFlag();
00322         
00323         Timeout t = BlueNRGGap::getInstance().getAdvTimeout();
00324         t.detach(); /* disable the callback from the timeout */
00325 
00326     }
00327 }
00328 #endif /* AST_FOR_MBED_OS */
00329     
00330 /**************************************************************************/
00331 /*!
00332     @brief  Starts the BLE HW, initialising any services that were
00333             added before this function was called.
00334     
00335     @param[in]  params
00336                 Basic advertising details, including the advertising
00337                 delay, timeout and how the device should be advertised
00338                 
00339     @note   All services must be added before calling this function!
00340 
00341     @returns    ble_error_t
00342 
00343     @retval     BLE_ERROR_NONE
00344                 Everything executed properly
00345 
00346     @section EXAMPLE
00347 
00348     @code
00349 
00350     @endcode
00351 */
00352 /**************************************************************************/
00353 
00354 ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams &params)
00355 {
00356     tBleStatus ret;
00357 
00358     /* Make sure we support the advertising type */
00359     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
00360         /* ToDo: This requires a propery security implementation, etc. */
00361         return BLE_ERROR_NOT_IMPLEMENTED;
00362     }
00363 
00364     /* Check interval range */
00365     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
00366         /* Min delay is slightly longer for unconnectable devices */
00367         if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
00368                 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
00369             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00370         }
00371     } else {
00372         if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
00373                 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
00374             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00375         }
00376     }
00377 
00378     /* Check timeout is zero for Connectable Directed */
00379     if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
00380         /* Timeout must be 0 with this type, although we'll never get here */
00381         /* since this isn't implemented yet anyway */
00382         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00383     }
00384 
00385     /* Check timeout for other advertising types */
00386     if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
00387             (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
00388         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00389     }
00390 
00391     /* set scan response data */
00392     ret = hci_le_set_scan_resp_data(scan_rsp_length, scan_response_payload);
00393     if(BLE_STATUS_SUCCESS!=ret) {
00394         PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
00395         switch (ret) {
00396           case BLE_STATUS_TIMEOUT:
00397             return BLE_STACK_BUSY;
00398           default:
00399             return BLE_ERROR_UNSPECIFIED;
00400         }
00401     }
00402 
00403     /*aci_gap_set_discoverable(Advertising_Event_Type, Adv_min_intvl, Adv_Max_Intvl, Addr_Type, Adv_Filter_Policy,
00404                         Local_Name_Length, local_name, service_uuid_length, service_uuid_list, Slave_conn_intvl_min, Slave_conn_intvl_max);*/
00405     /*LINK_LAYER.H DESCRIBES THE ADVERTISING TYPES*/ 
00406 
00407     // Enable the else branch if you want to set default device name
00408     char* name = NULL;
00409     uint8_t nameLen = 0; 
00410     if(local_name!=NULL) {
00411         name = (char*)local_name;
00412         PRINTF("name=%s\n\r", name); 
00413         nameLen = local_name_length;
00414     } /*else {
00415         char str[] = "ST_BLE_DEV";
00416         name = new char[strlen(str)+1];
00417         name[0] = AD_TYPE_COMPLETE_LOCAL_NAME;
00418         strcpy(name+1, str);
00419         nameLen = strlen(name);
00420         PRINTF("nameLen=%d\n\r", nameLen);
00421         PRINTF("name=%s\n\r", name);      
00422     }*/
00423 
00424     advtInterval = params.getIntervalInADVUnits(); // set advtInterval in case it is not already set by user application  
00425     ret = aci_gap_set_discoverable(params.getAdvertisingType(), // Advertising_Event_Type                                
00426         advtInterval,   // Adv_Interval_Min
00427         advtInterval,   // Adv_Interval_Max
00428         PUBLIC_ADDR, // Address_Type 
00429         NO_WHITE_LIST_USE,  // Adv_Filter_Policy
00430         nameLen, //local_name_length, // Local_Name_Length
00431         (const char*)name, //local_name, // Local_Name
00432         servUuidlength,  //Service_Uuid_Length
00433         servUuidData, //Service_Uuid_List
00434         0, // Slave_Conn_Interval_Min
00435         0);  // Slave_Conn_Interval_Max
00436 
00437     
00438     PRINTF("!!!setting discoverable (servUuidlength=0x%x)\n", servUuidlength);
00439     if(BLE_STATUS_SUCCESS!=ret) {
00440        PRINTF("error occurred while setting discoverable (ret=0x%x)\n", ret);
00441        switch (ret) {
00442          case BLE_STATUS_INVALID_PARAMS:
00443            return BLE_ERROR_INVALID_PARAM;
00444          case ERR_COMMAND_DISALLOWED:
00445            return BLE_ERROR_OPERATION_NOT_PERMITTED;
00446          case ERR_UNSUPPORTED_FEATURE:
00447            return BLE_ERROR_NOT_IMPLEMENTED;
00448          case BLE_STATUS_TIMEOUT:
00449            return BLE_STACK_BUSY;
00450          default:
00451            return BLE_ERROR_UNSPECIFIED;
00452        }
00453     }
00454 
00455     // Before updating the ADV data, delete COMPLETE_LOCAL_NAME and TX_POWER_LEVEL fields (if present)
00456     if(AdvLen>0) {
00457       if(name!=NULL) {
00458         PRINTF("!!!calling aci_gap_delete_ad_type AD_TYPE_COMPLETE_LOCAL_NAME!!!\n");
00459         ret = aci_gap_delete_ad_type(AD_TYPE_COMPLETE_LOCAL_NAME);
00460         if (BLE_STATUS_SUCCESS!=ret){
00461           PRINTF("aci_gap_delete_ad_type failed return=%d\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       }
00470 
00471       // If ADV Data Type is SERVICE DATA or MANUFACTURER SPECIFIC DATA,
00472       // we need to delete it to make the needed room in ADV payload
00473       if(AdvData[1]==AD_TYPE_SERVICE_DATA || AdvData[1]==AD_TYPE_MANUFACTURER_SPECIFIC_DATA) {
00474         PRINTF("!!!calling aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL)!!!\n");
00475         ret = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL);
00476         if (BLE_STATUS_SUCCESS!=ret){
00477           PRINTF("aci_gap_delete_ad_type failed return=%d\n", ret);
00478           switch (ret) {
00479             case BLE_STATUS_TIMEOUT:
00480               return BLE_STACK_BUSY;
00481             default:
00482               return BLE_ERROR_UNSPECIFIED;
00483           }
00484         }
00485       }
00486    
00487       ret = aci_gap_update_adv_data(AdvLen, AdvData);
00488       if(BLE_STATUS_SUCCESS!=ret) {
00489         PRINTF("error occurred while adding adv data (ret=0x%x)\n", ret);
00490           switch (ret) {
00491             case BLE_STATUS_TIMEOUT:
00492               return BLE_STACK_BUSY;
00493             default:
00494               return BLE_ERROR_UNSPECIFIED;
00495           }
00496       }
00497       
00498     } // AdvLen>0
00499 
00500     state.advertising = 1;
00501 
00502     AdvToFlag = false;
00503     if(params.getTimeout() != 0) {
00504         PRINTF("!!! attaching to!!!\n");
00505         // ANDREA: mbedOS
00506 #ifdef AST_FOR_MBED_OS
00507         minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout()));
00508 #else
00509         advTimeout.attach(advTimeoutCB, params.getTimeout());
00510 #endif
00511     }
00512     
00513     return BLE_ERROR_NONE;
00514 }
00515 
00516 /**************************************************************************/
00517 /*!
00518     @brief  Stops the BLE HW and disconnects from any devices
00519 
00520     @returns    ble_error_t
00521 
00522     @retval     BLE_ERROR_NONE
00523                 Everything executed properly
00524 
00525     @section EXAMPLE
00526 
00527     @code
00528 
00529     @endcode
00530 */
00531 /**************************************************************************/
00532 ble_error_t BlueNRGGap::stopAdvertising(void)
00533 {
00534     tBleStatus ret;
00535     
00536     if(state.advertising == 1) {
00537         //Set non-discoverable to stop advertising
00538         ret = aci_gap_set_non_discoverable();
00539         
00540         if (BLE_STATUS_SUCCESS!=ret){
00541             PRINTF("Error in stopping advertisement (ret=0x%x)!!\n\r", ret) ;
00542             switch (ret) {
00543               case ERR_COMMAND_DISALLOWED:
00544                 return BLE_ERROR_OPERATION_NOT_PERMITTED;
00545               case BLE_STATUS_TIMEOUT:
00546                 return BLE_STACK_BUSY;
00547               default:
00548                 return BLE_ERROR_UNSPECIFIED;
00549             }
00550         }
00551         PRINTF("Advertisement stopped!!\n\r") ;
00552         //Set GapState_t::advertising state
00553         state.advertising = 0;
00554     }
00555     
00556     return BLE_ERROR_NONE;
00557 }
00558 
00559 /**************************************************************************/
00560 /*!
00561     @brief  Disconnects if we are connected to a central device
00562 
00563     @param[in]  reason
00564                 Disconnection Reason
00565                 
00566     @returns    ble_error_t
00567 
00568     @retval     BLE_ERROR_NONE
00569                 Everything executed properly
00570 
00571     @section EXAMPLE
00572 
00573     @code
00574 
00575     @endcode
00576 */
00577 /**************************************************************************/
00578 ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason)
00579 {
00580     /* avoid compiler warnings about unused variables */
00581     (void)reason;
00582 
00583     tBleStatus ret;
00584     //For Reason codes check BlueTooth HCI Spec
00585     
00586     if(m_connectionHandle != BLE_CONN_HANDLE_INVALID) {
00587         ret = aci_gap_terminate(m_connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. 
00588 
00589         if (BLE_STATUS_SUCCESS != ret){
00590             PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
00591             switch (ret) {
00592               case ERR_COMMAND_DISALLOWED:
00593                 return BLE_ERROR_OPERATION_NOT_PERMITTED;
00594               case BLE_STATUS_TIMEOUT:
00595                 return BLE_STACK_BUSY;
00596               default:
00597                 return BLE_ERROR_UNSPECIFIED;
00598             }
00599         }
00600         
00601         //PRINTF("Disconnected from localhost!!\n\r") ;
00602         m_connectionHandle = BLE_CONN_HANDLE_INVALID;
00603     }
00604     
00605     return BLE_ERROR_NONE;
00606 }
00607 
00608 /**************************************************************************/
00609 /*!
00610     @brief  Disconnects if we are connected to a central device
00611 
00612     @param[in]  reason
00613                 Disconnection Reason
00614                 
00615     @returns    ble_error_t
00616 
00617     @retval     BLE_ERROR_NONE
00618                 Everything executed properly
00619 
00620     @section EXAMPLE
00621 
00622     @code
00623 
00624     @endcode
00625 */
00626 /**************************************************************************/
00627 ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason)
00628 {
00629     /* avoid compiler warnings about unused variables */
00630     (void)reason;
00631 
00632     tBleStatus ret;
00633     //For Reason codes check BlueTooth HCI Spec
00634     
00635     if(connectionHandle != BLE_CONN_HANDLE_INVALID) {
00636         ret = aci_gap_terminate(connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. 
00637 
00638         if (BLE_STATUS_SUCCESS != ret){
00639             PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
00640             switch (ret) {
00641               case ERR_COMMAND_DISALLOWED:
00642                 return BLE_ERROR_OPERATION_NOT_PERMITTED;
00643               case BLE_STATUS_TIMEOUT:
00644                 return BLE_STACK_BUSY;
00645               default:
00646                 return BLE_ERROR_UNSPECIFIED;
00647             }
00648         }
00649         
00650         //PRINTF("Disconnected from localhost!!\n\r") ;
00651         m_connectionHandle = BLE_CONN_HANDLE_INVALID;
00652     }
00653     
00654     return BLE_ERROR_NONE;
00655 }
00656 
00657 /**************************************************************************/
00658 /*!
00659     @brief  Sets the 16-bit connection handle
00660     
00661     @param[in]  con_handle
00662                 Connection Handle which is set in the Gap Instance
00663                 
00664     @returns    void
00665 */
00666 /**************************************************************************/
00667 void BlueNRGGap::setConnectionHandle(uint16_t con_handle)
00668 {
00669     m_connectionHandle = con_handle;
00670 }
00671 
00672 /**************************************************************************/
00673 /*!
00674     @brief  Gets the 16-bit connection handle
00675     
00676     @param[in]  void
00677                 
00678     @returns    uint16_t
00679                 Connection Handle of the Gap Instance
00680 */
00681 /**************************************************************************/
00682 uint16_t BlueNRGGap::getConnectionHandle(void)
00683 {
00684     return m_connectionHandle;
00685 }
00686 
00687 /**************************************************************************/
00688 /*!
00689     @brief      Sets the BLE device address. SetAddress will reset the BLE
00690                 device and re-initialize BTLE. Will not start advertising.
00691 
00692     @param[in]  type
00693                 Type of Address
00694     
00695     @param[in]  address[6]
00696                 Value of the Address to be set
00697                 
00698     @returns    ble_error_t
00699 
00700     @section EXAMPLE
00701 
00702     @code
00703 
00704     @endcode
00705 */
00706 /**************************************************************************/
00707 ble_error_t BlueNRGGap::setAddress(AddressType_t type, const Address_t address)
00708 {
00709     if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
00710         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00711     }
00712     
00713     addr_type = type;
00714     //copy address to bdAddr[6]
00715     for(int i=0; i<BDADDR_SIZE; i++) {
00716         bdaddr[i] = address[i];
00717         //PRINTF("i[%d]:0x%x\n\r",i,bdaddr[i]);
00718     }
00719     
00720     if(!isSetAddress) isSetAddress = true;
00721     
00722     return BLE_ERROR_NONE;
00723 }
00724 
00725 /**************************************************************************/
00726 /*!
00727     @brief      Returns boolean if the address of the device has been set
00728                 or not
00729                 
00730     @returns    bool
00731 
00732     @section EXAMPLE
00733 
00734     @code
00735 
00736     @endcode
00737 */
00738 /**************************************************************************/
00739 bool BlueNRGGap::getIsSetAddress() 
00740 {
00741     return isSetAddress;   
00742 }
00743 
00744 /**************************************************************************/
00745 /*!
00746     @brief      Returns the address of the device if set
00747 
00748     @returns    Pointer to the address if Address is set else NULL
00749 
00750     @section EXAMPLE
00751 
00752     @code
00753 
00754     @endcode
00755 */
00756 /**************************************************************************/
00757 ble_error_t BlueNRGGap::getAddress(AddressType_t *typeP, Address_t address) 
00758 {
00759     *typeP = addr_type;//Gap::ADDR_TYPE_PUBLIC;
00760     
00761     if(isSetAddress)
00762     {
00763         for(int i=0; i<BDADDR_SIZE; i++) {
00764             address[i] = bdaddr[i];
00765             //PRINTF("i[%d]:0x%x\n\r",i,bdaddr[i]);
00766         }
00767     }
00768         
00769     return BLE_ERROR_NONE;
00770 }
00771 
00772 /**************************************************************************/
00773 /*!
00774     @brief      obtains preferred connection params
00775 
00776     @returns    ble_error_t
00777 
00778     @section EXAMPLE
00779 
00780     @code
00781 
00782     @endcode
00783 */
00784 /**************************************************************************/
00785 ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) 
00786 {
00787     /* avoid compiler warnings about unused variables */
00788     (void)params;
00789 
00790     return BLE_ERROR_NONE;
00791 }
00792 
00793 
00794 /**************************************************************************/
00795 /*!
00796     @brief      sets preferred connection params
00797 
00798     @returns    ble_error_t
00799 
00800     @section EXAMPLE
00801 
00802     @code
00803 
00804     @endcode
00805 */
00806 /**************************************************************************/
00807 ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) 
00808 {
00809     /* avoid compiler warnings about unused variables */
00810     (void)params;
00811 
00812     return BLE_ERROR_NONE;
00813 }
00814 
00815 /**************************************************************************/
00816 /*!
00817     @brief      updates preferred connection params
00818 
00819     @returns    ble_error_t
00820 
00821     @section EXAMPLE
00822 
00823     @code
00824 
00825     @endcode
00826 */
00827 /**************************************************************************/
00828 ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params)
00829 {
00830     /* avoid compiler warnings about unused variables */
00831     (void) handle;
00832     (void)params;
00833 
00834     return BLE_ERROR_NONE;
00835 }
00836 
00837 /**************************************************************************/
00838 /*!
00839     @brief  Sets the Device Name Characteristic 
00840 
00841     @param[in]  deviceName
00842                 pointer to device name to be set
00843 
00844     @returns    ble_error_t
00845 
00846     @retval     BLE_ERROR_NONE
00847                 Everything executed properly
00848 
00849     @section EXAMPLE
00850 
00851     @code
00852 
00853     @endcode
00854 */
00855 /**************************************************************************/
00856 ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) 
00857 {
00858     tBleStatus ret;
00859     uint8_t nameLen = 0;     
00860     
00861     DeviceName = (uint8_t *)deviceName;
00862     //PRINTF("SetDeviceName=%s\n\r", DeviceName);
00863     
00864     nameLen = strlen((const char*)DeviceName);
00865     //PRINTF("DeviceName Size=%d\n\r", nameLen); 
00866     
00867     ret = aci_gatt_update_char_value(g_gap_service_handle, 
00868     g_device_name_char_handle, 
00869     0, 
00870     nameLen, 
00871     (uint8_t *)DeviceName);
00872 
00873     if (BLE_STATUS_SUCCESS != ret){
00874         PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ;
00875         switch (ret) {
00876           case BLE_STATUS_INVALID_HANDLE:
00877           case BLE_STATUS_INVALID_PARAMETER:
00878             return BLE_ERROR_INVALID_PARAM;
00879           case BLE_STATUS_INSUFFICIENT_RESOURCES:
00880             return BLE_ERROR_NO_MEM;
00881           case BLE_STATUS_TIMEOUT:
00882             return BLE_STACK_BUSY;
00883           default:
00884             return BLE_ERROR_UNSPECIFIED;
00885         }
00886     }
00887 
00888     return BLE_ERROR_NONE;
00889 }
00890 
00891 /**************************************************************************/
00892 /*!
00893     @brief  Gets the Device Name Characteristic 
00894 
00895     @param[in]  deviceName
00896                 pointer to device name                 
00897 
00898     @param[in]  lengthP
00899                 pointer to device name length                
00900 
00901     @returns    ble_error_t
00902 
00903     @retval     BLE_ERROR_NONE
00904                 Everything executed properly
00905 
00906     @section EXAMPLE
00907 
00908     @code
00909 
00910     @endcode
00911 */
00912 /**************************************************************************/
00913 ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) 
00914 {   
00915     if(DeviceName==NULL) 
00916       return BLE_ERROR_UNSPECIFIED;
00917     
00918     strcpy((char*)deviceName, (const char*)DeviceName);
00919     //PRINTF("GetDeviceName=%s\n\r", deviceName);
00920     
00921     *lengthP = strlen((const char*)DeviceName);
00922     //PRINTF("DeviceName Size=%d\n\r", *lengthP); 
00923     
00924     return BLE_ERROR_NONE;
00925 }
00926 
00927 /**************************************************************************/
00928 /*!
00929     @brief  Sets the Device Appearance Characteristic 
00930 
00931     @param[in]  appearance
00932                 device appearance      
00933 
00934     @returns    ble_error_t
00935 
00936     @retval     BLE_ERROR_NONE
00937                 Everything executed properly
00938 
00939     @section EXAMPLE
00940 
00941     @code
00942 
00943     @endcode
00944 */
00945 /**************************************************************************/
00946 ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance)
00947 {
00948     tBleStatus ret;
00949 
00950     /* 
00951     Tested with GapAdvertisingData::GENERIC_PHONE. 
00952     for other appearances BLE Scanner android app is not behaving properly 
00953     */
00954     //char deviceAppearance[2];   
00955     STORE_LE_16(deviceAppearance, appearance);                 
00956     PRINTF("input: incoming = %d deviceAppearance= 0x%x 0x%x\n\r", appearance, deviceAppearance[1], deviceAppearance[0]);
00957     
00958     ret = aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (uint8_t *)deviceAppearance);
00959     if (BLE_STATUS_SUCCESS == ret){
00960         return BLE_ERROR_NONE;
00961     }
00962 
00963     PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret) ;
00964     switch (ret) {
00965       case BLE_STATUS_INVALID_HANDLE:
00966       case BLE_STATUS_INVALID_PARAMETER:
00967         return BLE_ERROR_INVALID_PARAM;
00968       case BLE_STATUS_INSUFFICIENT_RESOURCES:
00969         return BLE_ERROR_NO_MEM;
00970       case BLE_STATUS_TIMEOUT:
00971         return BLE_STACK_BUSY;
00972       default:
00973         return BLE_ERROR_UNSPECIFIED;
00974     }
00975 }
00976 
00977 /**************************************************************************/
00978 /*!
00979     @brief  Gets the Device Appearance Characteristic
00980 
00981     @param[in]  appearance
00982                 pointer to device appearance value      
00983 
00984     @returns    ble_error_t
00985 
00986     @retval     BLE_ERROR_NONE
00987                 Everything executed properly
00988 
00989     @section EXAMPLE
00990 
00991     @code
00992 
00993     @endcode
00994 */
00995 /**************************************************************************/
00996 ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
00997 {
00998     uint16_t devP;
00999     if(!appearanceP) return BLE_ERROR_PARAM_OUT_OF_RANGE;
01000     devP = ((uint16_t)(0x0000|deviceAppearance[0])) | (((uint16_t)(0x0000|deviceAppearance[1]))<<8);
01001     strcpy((char*)appearanceP, (const char*)&devP);
01002     
01003     return BLE_ERROR_NONE;    
01004 }
01005 
01006 /**************************************************************************/
01007 /*!
01008     @brief  Gets the value of maximum advertising interval in ms
01009 
01010     @returns    uint16_t
01011 
01012     @retval     value of maximum advertising interval in ms
01013                 
01014     @section EXAMPLE
01015 
01016     @code
01017 
01018     @endcode
01019 */
01020 /**************************************************************************/
01021 uint16_t BlueNRGGap::getMaxAdvertisingInterval(void) const  {
01022     return advtInterval;
01023 } 
01024 
01025 
01026 /**************************************************************************/
01027 /*!
01028     @brief  Gets the value of minimum advertising interval in ms
01029 
01030     @returns    uint16_t
01031 
01032     @retval     value of minimum advertising interval in ms
01033                 
01034     @section EXAMPLE
01035 
01036     @code
01037 
01038     @endcode
01039 */
01040 /**************************************************************************/
01041 uint16_t BlueNRGGap::getMinAdvertisingInterval(void) const {    
01042     return 0;    // minimum Advertising interval is 0
01043 }
01044 
01045 /**************************************************************************/
01046 /*!
01047     @brief  Gets the value of minimum non connectable advertising interval in ms
01048 
01049     @returns    uint16_t
01050 
01051     @retval     value of minimum non connectable advertising interval in ms
01052                 
01053     @section EXAMPLE
01054 
01055     @code
01056 
01057     @endcode
01058 */
01059 /**************************************************************************/
01060 uint16_t BlueNRGGap::getMinNonConnectableAdvertisingInterval(void) const {     
01061     return BLE_GAP_ADV_NONCON_INTERVAL_MIN;    
01062 }
01063 
01064 GapScanningParams* BlueNRGGap::getScanningParams(void)
01065 {
01066   return &_scanningParams;
01067 }
01068 
01069 static void radioScanning(void)
01070 {
01071   GapScanningParams* scanningParams = BlueNRGGap::getInstance().getScanningParams();
01072 
01073   BlueNRGGap::getInstance().startRadioScan(*scanningParams);
01074 }
01075 
01076 static void makeConnection(void)
01077 {
01078   BlueNRGGap::getInstance().createConnection();
01079 }
01080 
01081 // ANDREA
01082 void BlueNRGGap::Discovery_CB(Reason_t reason,
01083                               uint8_t adv_type,
01084                               uint8_t *addr_type,
01085                               uint8_t *addr,
01086                               uint8_t *data_length,
01087                               uint8_t *data,
01088                               uint8_t *RSSI)
01089 {
01090   /* avoid compiler warnings about unused variables */
01091   (void)addr_type;
01092 
01093   switch (reason) {
01094   case DEVICE_FOUND:
01095     {
01096       GapAdvertisingParams::AdvertisingType_t type;
01097       bool isScanResponse = false;
01098       switch(adv_type) {
01099       case ADV_IND:
01100         type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
01101         break;
01102       case ADV_DIRECT_IND:
01103         type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED;
01104         break;
01105       case ADV_SCAN_IND:
01106       case SCAN_RSP:
01107         type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED;
01108         isScanResponse = true;
01109         break;
01110       case ADV_NONCONN_IND:
01111         type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED;
01112         break;
01113       default:
01114         type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
01115       }
01116     
01117       PRINTF("adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n",
01118            addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
01119       processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data);
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. Otherwise, we restart the scanning.
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 or re-scanning procedures
01133     uint16_t delay = 2*(_scanningParams.getInterval());
01134 #ifdef AST_FOR_MBED_OS
01135     if(_connecting) {
01136       minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay));
01137     } else {
01138       minar::Scheduler::postCallback(radioScanning).delay(minar::milliseconds(delay));
01139     }
01140 #else
01141     Clock_Wait(delay);
01142     if(_connecting) {
01143       makeConnection();
01144     } else {
01145       radioScanning();
01146     }
01147 #endif
01148     break;
01149   }
01150 }
01151 
01152 ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams)
01153 {
01154   
01155   tBleStatus ret = BLE_STATUS_SUCCESS;
01156   
01157   PRINTF("Scanning...\n\r");
01158   
01159   // We received a start scan request from the application level.
01160   // If we are on X-NUCLEO-IDB04A1 (playing a single role at time),
01161   // we need to re-init our expansion board to specify the GAP CENTRAL ROLE
01162   if(!btle_reinited) {
01163     btle_init(isSetAddress, GAP_CENTRAL_ROLE_IDB04A1);
01164     btle_reinited = true;
01165     
01166     PRINTF("BTLE re-init\n\r");
01167   }
01168   
01169   ret = aci_gap_start_general_discovery_proc(scanningParams.getInterval(),
01170                          scanningParams.getWindow(),
01171                          addr_type,
01172                          1); // 1 to filter duplicates
01173   
01174   if (ret != BLE_STATUS_SUCCESS) {
01175     printf("Start Discovery Procedure failed (0x%02X)\n\r", ret);
01176     return BLE_ERROR_UNSPECIFIED; 
01177   } else {
01178     PRINTF("Discovery Procedure Started\n");
01179     _scanning = true;
01180     return BLE_ERROR_NONE; 
01181   }
01182 }
01183 
01184 ble_error_t BlueNRGGap::stopScan() {
01185   tBleStatus ret = BLE_STATUS_SUCCESS;
01186   
01187   ret = aci_gap_terminate_gap_procedure(GENERAL_DISCOVERY_PROCEDURE);
01188   
01189   if (ret != BLE_STATUS_SUCCESS) {
01190     printf("GAP Terminate Gap Procedure failed\n");
01191     return BLE_ERROR_UNSPECIFIED; 
01192   } else {
01193     PRINTF("Discovery Procedure Terminated\n");
01194     return BLE_ERROR_NONE; 
01195   }
01196 }
01197 
01198 /**************************************************************************/
01199 /*!
01200     @brief  set Tx power level
01201     @param[in] txPower Transmission Power level
01202     @returns    ble_error_t
01203 */
01204 /**************************************************************************/
01205 ble_error_t BlueNRGGap::setTxPower(int8_t txPower)
01206 {
01207     tBleStatus ret;
01208     
01209     int8_t enHighPower = 0;
01210     int8_t paLevel = 0;
01211 
01212     int8_t dbmActuallySet = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel);
01213 
01214 #ifndef DEBUG
01215     /* avoid compiler warnings about unused variables */
01216     (void)dbmActuallySet;
01217 #endif
01218     
01219     PRINTF("txPower=%d, dbmActuallySet=%d\n\r", txPower, dbmActuallySet);
01220     PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);                    
01221     ret = aci_hal_set_tx_power_level(enHighPower, paLevel);
01222     if(ret!=BLE_STATUS_SUCCESS) {
01223       return BLE_ERROR_UNSPECIFIED;
01224     }
01225 
01226     return BLE_ERROR_NONE;
01227 }
01228 
01229 /**************************************************************************/
01230 /*!
01231     @brief  get permitted Tx power values
01232     @param[in] values pointer to pointer to permitted power values
01233     @param[in] num number of values   
01234 */
01235 /**************************************************************************/
01236 void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
01237     static const int8_t permittedTxValues[] = {
01238         -18, -14, -11, -8, -4, -1, 1, 5, -15, -11, -8, -5, -2, 1, 4, 8
01239     };
01240 
01241     *valueArrayPP = permittedTxValues;
01242     *countP = sizeof(permittedTxValues) / sizeof(int8_t);
01243 }
01244 
01245 ble_error_t BlueNRGGap::createConnection ()
01246 {
01247   tBleStatus ret;
01248   
01249   /*
01250     Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, 
01251     Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max    
01252   */
01253   ret = aci_gap_create_connection(SCAN_P,
01254                   SCAN_L,
01255                   PUBLIC_ADDR,
01256                   (unsigned char*)_peerAddr,
01257                   PUBLIC_ADDR,
01258                   CONN_P1, CONN_P2, 0,
01259                   SUPERV_TIMEOUT, CONN_L1 , CONN_L2);
01260 
01261   _connecting = false;
01262   
01263   if (ret != BLE_STATUS_SUCCESS) {
01264     printf("Error while starting connection (ret=0x%02X).\n\r", ret);
01265     return BLE_ERROR_UNSPECIFIED;
01266   } else {
01267     PRINTF("Connection started.\n");
01268     return BLE_ERROR_NONE;
01269   }
01270 }
01271 
01272 ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr,
01273                                  Gap::AddressType_t peerAddrType,
01274                                  const ConnectionParams_t *connectionParams,
01275                                  const GapScanningParams *scanParams)
01276 {
01277   /* avoid compiler warnings about unused variables */
01278   (void)peerAddrType;
01279   (void)connectionParams;
01280   (void)scanParams;
01281 
01282     // Save the peer address
01283   for(int i=0; i<BDADDR_SIZE; i++) {
01284     _peerAddr[i] = peerAddr[i];
01285   }
01286 
01287   _connecting = true;
01288 
01289   if(_scanning) {
01290     stopScan();
01291   } else {
01292     PRINTF("Calling createConnection from connect()\n\r");
01293     return createConnection();
01294   }
01295   
01296   return BLE_ERROR_NONE;
01297 }