aapje monkey / X_NUCLEO_IDB0XA1

Fork of X_NUCLEO_IDB0XA1 by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BlueNRGGap.cpp Source File

BlueNRGGap.cpp

Go to the documentation of this file.
00001 /* mbed Microcontroller Library
00002 * Copyright (c) 2006-2013 ARM Limited
00003 *
00004 * Licensed under the Apache License, Version 2.0 (the "License");
00005 * you may not use this file except in compliance with the License.
00006 * You may obtain a copy of the License at
00007 *
00008 *     http://www.apache.org/licenses/LICENSE-2.0
00009 *
00010 * Unless required by applicable law or agreed to in writing, software
00011 * distributed under the License is distributed on an "AS IS" BASIS,
00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 * See the License for the specific language governing permissions and
00014 * limitations under the License.
00015 */
00016 
00017 
00018 /**
00019   ******************************************************************************
00020   * @file    BlueNRGGap.cpp 
00021   * @author  STMicroelectronics
00022   * @brief   Implementation of BLE_API Gap Class
00023   ******************************************************************************
00024   * @copy
00025   *
00026   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00027   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
00028   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
00029   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00030   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00031   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00032   *
00033   * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
00034   */ 
00035 
00036 // 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         // Update the ADV data if we are already in ADV mode
00288         if(AdvLen > 0 && state.advertising == 1) {
00289  
00290             tBleStatus ret = aci_gap_update_adv_data(AdvLen, AdvData);
00291             if(BLE_STATUS_SUCCESS!=ret) {
00292                 PRINTF("error occurred while adding adv data (ret=0x%x)\n", ret);
00293                 switch (ret) {
00294                     case BLE_STATUS_TIMEOUT:
00295                         return BLE_STACK_BUSY;
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 // ANDREA: mbedOS
00316 #ifdef AST_FOR_MBED_OS
00317 static void advTimeoutCB(void)
00318 {
00319     Gap::GapState_t state;
00320     
00321     state = BlueNRGGap::getInstance().getState();
00322     if (state.advertising == 1) {
00323         
00324         BlueNRGGap::getInstance().stopAdvertising();
00325         
00326     }
00327 }
00328 #else
00329 static void advTimeoutCB(void)
00330 {
00331     Gap::GapState_t state;
00332     
00333     state = BlueNRGGap::getInstance().getState();
00334     if (state.advertising == 1) {
00335         
00336         BlueNRGGap::getInstance().setAdvToFlag();
00337         
00338         Timeout t = BlueNRGGap::getInstance().getAdvTimeout();
00339         t.detach(); /* disable the callback from the timeout */
00340 
00341     }
00342 }
00343 #endif /* AST_FOR_MBED_OS */
00344     
00345 /**************************************************************************/
00346 /*!
00347     @brief  Starts the BLE HW, initialising any services that were
00348             added before this function was called.
00349     
00350     @param[in]  params
00351                 Basic advertising details, including the advertising
00352                 delay, timeout and how the device should be advertised
00353                 
00354     @note   All services must be added before calling this function!
00355 
00356     @returns    ble_error_t
00357 
00358     @retval     BLE_ERROR_NONE
00359                 Everything executed properly
00360 
00361     @section EXAMPLE
00362 
00363     @code
00364 
00365     @endcode
00366 */
00367 /**************************************************************************/
00368 
00369 ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams &params)
00370 {
00371     tBleStatus ret;
00372 
00373     /* Make sure we support the advertising type */
00374     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
00375         /* ToDo: This requires a propery 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     /* set scan response data */
00407     ret = hci_le_set_scan_resp_data(scan_rsp_length, scan_response_payload);
00408     if(BLE_STATUS_SUCCESS!=ret) {
00409         PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
00410         switch (ret) {
00411           case BLE_STATUS_TIMEOUT:
00412             return BLE_STACK_BUSY;
00413           default:
00414             return BLE_ERROR_UNSPECIFIED;
00415         }
00416     }
00417 
00418     /*aci_gap_set_discoverable(Advertising_Event_Type, Adv_min_intvl, Adv_Max_Intvl, Addr_Type, Adv_Filter_Policy,
00419                         Local_Name_Length, local_name, service_uuid_length, service_uuid_list, Slave_conn_intvl_min, Slave_conn_intvl_max);*/
00420     /*LINK_LAYER.H DESCRIBES THE ADVERTISING TYPES*/ 
00421 
00422     // Enable the else branch if you want to set default device name
00423     char* name = NULL;
00424     uint8_t nameLen = 0; 
00425     if(local_name!=NULL) {
00426         name = (char*)local_name;
00427         PRINTF("name=%s\n\r", name); 
00428         nameLen = local_name_length;
00429     } /*else {
00430         char str[] = "ST_BLE_DEV";
00431         name = new char[strlen(str)+1];
00432         name[0] = AD_TYPE_COMPLETE_LOCAL_NAME;
00433         strcpy(name+1, str);
00434         nameLen = strlen(name);
00435         PRINTF("nameLen=%d\n\r", nameLen);
00436         PRINTF("name=%s\n\r", name);      
00437     }*/
00438 
00439     advtInterval = params.getIntervalInADVUnits(); // set advtInterval in case it is not already set by user application  
00440     ret = aci_gap_set_discoverable(params.getAdvertisingType(), // Advertising_Event_Type                                
00441         advtInterval,   // Adv_Interval_Min
00442         advtInterval,   // Adv_Interval_Max
00443         PUBLIC_ADDR, // Address_Type 
00444         NO_WHITE_LIST_USE,  // Adv_Filter_Policy
00445         nameLen, //local_name_length, // Local_Name_Length
00446         (const char*)name, //local_name, // Local_Name
00447         servUuidlength,  //Service_Uuid_Length
00448         servUuidData, //Service_Uuid_List
00449         0, // Slave_Conn_Interval_Min
00450         0);  // Slave_Conn_Interval_Max
00451 
00452     
00453     PRINTF("!!!setting discoverable (servUuidlength=0x%x)\n", servUuidlength);
00454     if(BLE_STATUS_SUCCESS!=ret) {
00455        PRINTF("error occurred while setting discoverable (ret=0x%x)\n", ret);
00456        switch (ret) {
00457          case BLE_STATUS_INVALID_PARAMS:
00458            return BLE_ERROR_INVALID_PARAM;
00459          case ERR_COMMAND_DISALLOWED:
00460            return BLE_ERROR_OPERATION_NOT_PERMITTED;
00461          case ERR_UNSUPPORTED_FEATURE:
00462            return BLE_ERROR_NOT_IMPLEMENTED;
00463          case BLE_STATUS_TIMEOUT:
00464            return BLE_STACK_BUSY;
00465          default:
00466            return BLE_ERROR_UNSPECIFIED;
00467        }
00468     }
00469 
00470     // Before updating the ADV data, delete COMPLETE_LOCAL_NAME and TX_POWER_LEVEL fields (if present)
00471     if(AdvLen>0) {
00472       if(name!=NULL) {
00473         PRINTF("!!!calling aci_gap_delete_ad_type AD_TYPE_COMPLETE_LOCAL_NAME!!!\n");
00474         ret = aci_gap_delete_ad_type(AD_TYPE_COMPLETE_LOCAL_NAME);
00475         if (BLE_STATUS_SUCCESS!=ret){
00476           PRINTF("aci_gap_delete_ad_type failed return=%d\n", ret);
00477           switch (ret) {
00478             case BLE_STATUS_TIMEOUT:
00479               return BLE_STACK_BUSY;
00480             default:
00481               return BLE_ERROR_UNSPECIFIED;
00482           }
00483         }
00484       }
00485 
00486       // If ADV Data Type is SERVICE DATA or MANUFACTURER SPECIFIC DATA,
00487       // we need to delete it to make the needed room in ADV payload
00488       if(AdvData[1]==AD_TYPE_SERVICE_DATA || AdvData[1]==AD_TYPE_MANUFACTURER_SPECIFIC_DATA) {
00489         PRINTF("!!!calling aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL)!!!\n");
00490         ret = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL);
00491         if (BLE_STATUS_SUCCESS!=ret){
00492           PRINTF("aci_gap_delete_ad_type failed return=%d\n", ret);
00493           switch (ret) {
00494             case BLE_STATUS_TIMEOUT:
00495               return BLE_STACK_BUSY;
00496             default:
00497               return BLE_ERROR_UNSPECIFIED;
00498           }
00499         }
00500       }
00501    
00502       ret = aci_gap_update_adv_data(AdvLen, AdvData);
00503       if(BLE_STATUS_SUCCESS!=ret) {
00504         PRINTF("error occurred while adding adv data (ret=0x%x)\n", ret);
00505           switch (ret) {
00506             case BLE_STATUS_TIMEOUT:
00507               return BLE_STACK_BUSY;
00508             default:
00509               return BLE_ERROR_UNSPECIFIED;
00510           }
00511       }
00512       
00513     } // AdvLen>0
00514 
00515     state.advertising = 1;
00516 
00517     AdvToFlag = false;
00518     if(params.getTimeout() != 0) {
00519         PRINTF("!!! attaching to!!!\n");
00520         // ANDREA: mbedOS
00521 #ifdef AST_FOR_MBED_OS
00522         minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout()));
00523 #else
00524         advTimeout.attach(advTimeoutCB, params.getTimeout());
00525 #endif
00526     }
00527     
00528     return BLE_ERROR_NONE;
00529 }
00530 
00531 /**************************************************************************/
00532 /*!
00533     @brief  Stops the BLE HW and disconnects from any devices
00534 
00535     @returns    ble_error_t
00536 
00537     @retval     BLE_ERROR_NONE
00538                 Everything executed properly
00539 
00540     @section EXAMPLE
00541 
00542     @code
00543 
00544     @endcode
00545 */
00546 /**************************************************************************/
00547 ble_error_t BlueNRGGap::stopAdvertising(void)
00548 {
00549     tBleStatus ret;
00550     
00551     if(state.advertising == 1) {
00552         //Set non-discoverable to stop advertising
00553         ret = aci_gap_set_non_discoverable();
00554         
00555         if (BLE_STATUS_SUCCESS!=ret){
00556             PRINTF("Error in stopping advertisement (ret=0x%x)!!\n\r", ret) ;
00557             switch (ret) {
00558               case ERR_COMMAND_DISALLOWED:
00559                 return BLE_ERROR_OPERATION_NOT_PERMITTED;
00560               case BLE_STATUS_TIMEOUT:
00561                 return BLE_STACK_BUSY;
00562               default:
00563                 return BLE_ERROR_UNSPECIFIED;
00564             }
00565         }
00566         PRINTF("Advertisement stopped!!\n\r") ;
00567         //Set GapState_t::advertising state
00568         state.advertising = 0;
00569     }
00570     
00571     return BLE_ERROR_NONE;
00572 }
00573 
00574 /**************************************************************************/
00575 /*!
00576     @brief  Disconnects if we are connected to a central device
00577 
00578     @param[in]  reason
00579                 Disconnection Reason
00580                 
00581     @returns    ble_error_t
00582 
00583     @retval     BLE_ERROR_NONE
00584                 Everything executed properly
00585 
00586     @section EXAMPLE
00587 
00588     @code
00589 
00590     @endcode
00591 */
00592 /**************************************************************************/
00593 ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason)
00594 {
00595     /* avoid compiler warnings about unused variables */
00596     (void)reason;
00597 
00598     tBleStatus ret;
00599     //For Reason codes check BlueTooth HCI Spec
00600     
00601     if(m_connectionHandle != BLE_CONN_HANDLE_INVALID) {
00602         ret = aci_gap_terminate(m_connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. 
00603 
00604         if (BLE_STATUS_SUCCESS != ret){
00605             PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
00606             switch (ret) {
00607               case ERR_COMMAND_DISALLOWED:
00608                 return BLE_ERROR_OPERATION_NOT_PERMITTED;
00609               case BLE_STATUS_TIMEOUT:
00610                 return BLE_STACK_BUSY;
00611               default:
00612                 return BLE_ERROR_UNSPECIFIED;
00613             }
00614         }
00615         
00616         //PRINTF("Disconnected from localhost!!\n\r") ;
00617         m_connectionHandle = BLE_CONN_HANDLE_INVALID;
00618     }
00619     
00620     return BLE_ERROR_NONE;
00621 }
00622 
00623 /**************************************************************************/
00624 /*!
00625     @brief  Disconnects if we are connected to a central device
00626 
00627     @param[in]  reason
00628                 Disconnection Reason
00629                 
00630     @returns    ble_error_t
00631 
00632     @retval     BLE_ERROR_NONE
00633                 Everything executed properly
00634 
00635     @section EXAMPLE
00636 
00637     @code
00638 
00639     @endcode
00640 */
00641 /**************************************************************************/
00642 ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason)
00643 {
00644     /* avoid compiler warnings about unused variables */
00645     (void)reason;
00646 
00647     tBleStatus ret;
00648     //For Reason codes check BlueTooth HCI Spec
00649     
00650     if(connectionHandle != BLE_CONN_HANDLE_INVALID) {
00651         ret = aci_gap_terminate(connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. 
00652 
00653         if (BLE_STATUS_SUCCESS != ret){
00654             PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
00655             switch (ret) {
00656               case ERR_COMMAND_DISALLOWED:
00657                 return BLE_ERROR_OPERATION_NOT_PERMITTED;
00658               case BLE_STATUS_TIMEOUT:
00659                 return BLE_STACK_BUSY;
00660               default:
00661                 return BLE_ERROR_UNSPECIFIED;
00662             }
00663         }
00664         
00665         //PRINTF("Disconnected from localhost!!\n\r") ;
00666         m_connectionHandle = BLE_CONN_HANDLE_INVALID;
00667     }
00668     
00669     return BLE_ERROR_NONE;
00670 }
00671 
00672 /**************************************************************************/
00673 /*!
00674     @brief  Sets the 16-bit connection handle
00675     
00676     @param[in]  con_handle
00677                 Connection Handle which is set in the Gap Instance
00678                 
00679     @returns    void
00680 */
00681 /**************************************************************************/
00682 void BlueNRGGap::setConnectionHandle(uint16_t con_handle)
00683 {
00684     m_connectionHandle = con_handle;
00685 }
00686 
00687 /**************************************************************************/
00688 /*!
00689     @brief  Gets the 16-bit connection handle
00690     
00691     @param[in]  void
00692                 
00693     @returns    uint16_t
00694                 Connection Handle of the Gap Instance
00695 */
00696 /**************************************************************************/
00697 uint16_t BlueNRGGap::getConnectionHandle(void)
00698 {
00699     return m_connectionHandle;
00700 }
00701 
00702 /**************************************************************************/
00703 /*!
00704     @brief      Sets the BLE device address. SetAddress will reset the BLE
00705                 device and re-initialize BTLE. Will not start advertising.
00706 
00707     @param[in]  type
00708                 Type of Address
00709     
00710     @param[in]  address[6]
00711                 Value of the Address to be set
00712                 
00713     @returns    ble_error_t
00714 
00715     @section EXAMPLE
00716 
00717     @code
00718 
00719     @endcode
00720 */
00721 /**************************************************************************/
00722 ble_error_t BlueNRGGap::setAddress(AddressType_t type, const Address_t address)
00723 {
00724     if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
00725         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00726     }
00727     
00728     addr_type = type;
00729     //copy address to bdAddr[6]
00730     for(int i=0; i<BDADDR_SIZE; i++) {
00731         bdaddr[i] = address[i];
00732         //PRINTF("i[%d]:0x%x\n\r",i,bdaddr[i]);
00733     }
00734     
00735     if(!isSetAddress) isSetAddress = true;
00736     
00737     return BLE_ERROR_NONE;
00738 }
00739 
00740 /**************************************************************************/
00741 /*!
00742     @brief      Returns boolean if the address of the device has been set
00743                 or not
00744                 
00745     @returns    bool
00746 
00747     @section EXAMPLE
00748 
00749     @code
00750 
00751     @endcode
00752 */
00753 /**************************************************************************/
00754 bool BlueNRGGap::getIsSetAddress() 
00755 {
00756     return isSetAddress;   
00757 }
00758 
00759 /**************************************************************************/
00760 /*!
00761     @brief      Returns the address of the device if set
00762 
00763     @returns    Pointer to the address if Address is set else NULL
00764 
00765     @section EXAMPLE
00766 
00767     @code
00768 
00769     @endcode
00770 */
00771 /**************************************************************************/
00772 ble_error_t BlueNRGGap::getAddress(AddressType_t *typeP, Address_t address) 
00773 {
00774     *typeP = addr_type;//Gap::ADDR_TYPE_PUBLIC;
00775     
00776     if(isSetAddress)
00777     {
00778         for(int i=0; i<BDADDR_SIZE; i++) {
00779             address[i] = bdaddr[i];
00780             //PRINTF("i[%d]:0x%x\n\r",i,bdaddr[i]);
00781         }
00782     }
00783         
00784     return BLE_ERROR_NONE;
00785 }
00786 
00787 /**************************************************************************/
00788 /*!
00789     @brief      obtains preferred connection params
00790 
00791     @returns    ble_error_t
00792 
00793     @section EXAMPLE
00794 
00795     @code
00796 
00797     @endcode
00798 */
00799 /**************************************************************************/
00800 ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) 
00801 {
00802     /* avoid compiler warnings about unused variables */
00803     (void)params;
00804 
00805     return BLE_ERROR_NONE;
00806 }
00807 
00808 
00809 /**************************************************************************/
00810 /*!
00811     @brief      sets preferred connection params
00812 
00813     @returns    ble_error_t
00814 
00815     @section EXAMPLE
00816 
00817     @code
00818 
00819     @endcode
00820 */
00821 /**************************************************************************/
00822 ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) 
00823 {
00824     /* avoid compiler warnings about unused variables */
00825     (void)params;
00826 
00827     return BLE_ERROR_NONE;
00828 }
00829 
00830 /**************************************************************************/
00831 /*!
00832     @brief      updates preferred connection params
00833 
00834     @returns    ble_error_t
00835 
00836     @section EXAMPLE
00837 
00838     @code
00839 
00840     @endcode
00841 */
00842 /**************************************************************************/
00843 ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params)
00844 {
00845     /* avoid compiler warnings about unused variables */
00846     (void) handle;
00847     (void)params;
00848 
00849     return BLE_ERROR_NONE;
00850 }
00851 
00852 /**************************************************************************/
00853 /*!
00854     @brief  Sets the Device Name Characteristic 
00855 
00856     @param[in]  deviceName
00857                 pointer to device name to be set
00858 
00859     @returns    ble_error_t
00860 
00861     @retval     BLE_ERROR_NONE
00862                 Everything executed properly
00863 
00864     @section EXAMPLE
00865 
00866     @code
00867 
00868     @endcode
00869 */
00870 /**************************************************************************/
00871 ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) 
00872 {
00873     tBleStatus ret;
00874     uint8_t nameLen = 0;     
00875     
00876     DeviceName = (uint8_t *)deviceName;
00877     //PRINTF("SetDeviceName=%s\n\r", DeviceName);
00878     
00879     nameLen = strlen((const char*)DeviceName);
00880     //PRINTF("DeviceName Size=%d\n\r", nameLen); 
00881     
00882     ret = aci_gatt_update_char_value(g_gap_service_handle, 
00883     g_device_name_char_handle, 
00884     0, 
00885     nameLen, 
00886     (uint8_t *)DeviceName);
00887 
00888     if (BLE_STATUS_SUCCESS != ret){
00889         PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ;
00890         switch (ret) {
00891           case BLE_STATUS_INVALID_HANDLE:
00892           case BLE_STATUS_INVALID_PARAMETER:
00893             return BLE_ERROR_INVALID_PARAM;
00894           case BLE_STATUS_INSUFFICIENT_RESOURCES:
00895             return BLE_ERROR_NO_MEM;
00896           case BLE_STATUS_TIMEOUT:
00897             return BLE_STACK_BUSY;
00898           default:
00899             return BLE_ERROR_UNSPECIFIED;
00900         }
00901     }
00902 
00903     return BLE_ERROR_NONE;
00904 }
00905 
00906 /**************************************************************************/
00907 /*!
00908     @brief  Gets the Device Name Characteristic 
00909 
00910     @param[in]  deviceName
00911                 pointer to device name                 
00912 
00913     @param[in]  lengthP
00914                 pointer to device name length                
00915 
00916     @returns    ble_error_t
00917 
00918     @retval     BLE_ERROR_NONE
00919                 Everything executed properly
00920 
00921     @section EXAMPLE
00922 
00923     @code
00924 
00925     @endcode
00926 */
00927 /**************************************************************************/
00928 ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) 
00929 {   
00930     if(DeviceName==NULL) 
00931       return BLE_ERROR_UNSPECIFIED;
00932     
00933     strcpy((char*)deviceName, (const char*)DeviceName);
00934     //PRINTF("GetDeviceName=%s\n\r", deviceName);
00935     
00936     *lengthP = strlen((const char*)DeviceName);
00937     //PRINTF("DeviceName Size=%d\n\r", *lengthP); 
00938     
00939     return BLE_ERROR_NONE;
00940 }
00941 
00942 /**************************************************************************/
00943 /*!
00944     @brief  Sets the Device Appearance Characteristic 
00945 
00946     @param[in]  appearance
00947                 device appearance      
00948 
00949     @returns    ble_error_t
00950 
00951     @retval     BLE_ERROR_NONE
00952                 Everything executed properly
00953 
00954     @section EXAMPLE
00955 
00956     @code
00957 
00958     @endcode
00959 */
00960 /**************************************************************************/
00961 ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance)
00962 {
00963     tBleStatus ret;
00964 
00965     /* 
00966     Tested with GapAdvertisingData::GENERIC_PHONE. 
00967     for other appearances BLE Scanner android app is not behaving properly 
00968     */
00969     //char deviceAppearance[2];   
00970     STORE_LE_16(deviceAppearance, appearance);                 
00971     PRINTF("input: incoming = %d deviceAppearance= 0x%x 0x%x\n\r", appearance, deviceAppearance[1], deviceAppearance[0]);
00972     
00973     ret = aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (uint8_t *)deviceAppearance);
00974     if (BLE_STATUS_SUCCESS == ret){
00975         return BLE_ERROR_NONE;
00976     }
00977 
00978     PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret) ;
00979     switch (ret) {
00980       case BLE_STATUS_INVALID_HANDLE:
00981       case BLE_STATUS_INVALID_PARAMETER:
00982         return BLE_ERROR_INVALID_PARAM;
00983       case BLE_STATUS_INSUFFICIENT_RESOURCES:
00984         return BLE_ERROR_NO_MEM;
00985       case BLE_STATUS_TIMEOUT:
00986         return BLE_STACK_BUSY;
00987       default:
00988         return BLE_ERROR_UNSPECIFIED;
00989     }
00990 }
00991 
00992 /**************************************************************************/
00993 /*!
00994     @brief  Gets the Device Appearance Characteristic
00995 
00996     @param[in]  appearance
00997                 pointer to device appearance value      
00998 
00999     @returns    ble_error_t
01000 
01001     @retval     BLE_ERROR_NONE
01002                 Everything executed properly
01003 
01004     @section EXAMPLE
01005 
01006     @code
01007 
01008     @endcode
01009 */
01010 /**************************************************************************/
01011 ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
01012 {
01013     uint16_t devP;
01014     if(!appearanceP) return BLE_ERROR_PARAM_OUT_OF_RANGE;
01015     devP = ((uint16_t)(0x0000|deviceAppearance[0])) | (((uint16_t)(0x0000|deviceAppearance[1]))<<8);
01016     strcpy((char*)appearanceP, (const char*)&devP);
01017     
01018     return BLE_ERROR_NONE;    
01019 }
01020 
01021 /**************************************************************************/
01022 /*!
01023     @brief  Gets the value of maximum advertising interval in ms
01024 
01025     @returns    uint16_t
01026 
01027     @retval     value of maximum advertising interval in ms
01028                 
01029     @section EXAMPLE
01030 
01031     @code
01032 
01033     @endcode
01034 */
01035 /**************************************************************************/
01036 uint16_t BlueNRGGap::getMaxAdvertisingInterval(void) const  {
01037     return advtInterval;
01038 } 
01039 
01040 
01041 /**************************************************************************/
01042 /*!
01043     @brief  Gets the value of minimum advertising interval in ms
01044 
01045     @returns    uint16_t
01046 
01047     @retval     value of minimum advertising interval in ms
01048                 
01049     @section EXAMPLE
01050 
01051     @code
01052 
01053     @endcode
01054 */
01055 /**************************************************************************/
01056 uint16_t BlueNRGGap::getMinAdvertisingInterval(void) const {    
01057     return 0;    // minimum Advertising interval is 0
01058 }
01059 
01060 /**************************************************************************/
01061 /*!
01062     @brief  Gets the value of minimum non connectable advertising interval in ms
01063 
01064     @returns    uint16_t
01065 
01066     @retval     value of minimum non connectable advertising interval in ms
01067                 
01068     @section EXAMPLE
01069 
01070     @code
01071 
01072     @endcode
01073 */
01074 /**************************************************************************/
01075 uint16_t BlueNRGGap::getMinNonConnectableAdvertisingInterval(void) const {     
01076     return BLE_GAP_ADV_NONCON_INTERVAL_MIN;    
01077 }
01078 
01079 GapScanningParams* BlueNRGGap::getScanningParams(void)
01080 {
01081   return &_scanningParams;
01082 }
01083 
01084 static void radioScanning(void)
01085 {
01086   GapScanningParams* scanningParams = BlueNRGGap::getInstance().getScanningParams();
01087 
01088   BlueNRGGap::getInstance().startRadioScan(*scanningParams);
01089 }
01090 
01091 static void makeConnection(void)
01092 {
01093   BlueNRGGap::getInstance().createConnection();
01094 }
01095 
01096 // ANDREA
01097 void BlueNRGGap::Discovery_CB(Reason_t reason,
01098                               uint8_t adv_type,
01099                               uint8_t *addr_type,
01100                               uint8_t *addr,
01101                               uint8_t *data_length,
01102                               uint8_t *data,
01103                               uint8_t *RSSI)
01104 {
01105   /* avoid compiler warnings about unused variables */
01106   (void)addr_type;
01107 
01108   switch (reason) {
01109   case DEVICE_FOUND:
01110     {
01111       GapAdvertisingParams::AdvertisingType_t type;
01112       bool isScanResponse = false;
01113       switch(adv_type) {
01114       case ADV_IND:
01115         type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
01116         break;
01117       case ADV_DIRECT_IND:
01118         type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED;
01119         break;
01120       case ADV_SCAN_IND:
01121       case SCAN_RSP:
01122         type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED;
01123         isScanResponse = true;
01124         break;
01125       case ADV_NONCONN_IND:
01126         type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED;
01127         break;
01128       default:
01129         type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
01130       }
01131     
01132       PRINTF("adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n",
01133            addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
01134       processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data);
01135       PRINTF("!!!After processAdvertisementReport\n\r");
01136     }
01137     break;
01138     
01139   case DISCOVERY_COMPLETE:
01140     // The discovery is complete. If this is due to a stop scanning (i.e., the device
01141     // we are interested in has been found) and a connection has been requested
01142     // then we start the device connection. Otherwise, we restart the scanning.
01143     PRINTF("DISCOVERY_COMPLETE\n\r");
01144     _scanning = false;
01145 
01146     // Since the DISCOVERY_COMPLETE event can be received during the scanning interval,
01147     // we need to delay the starting of connection or re-scanning procedures
01148     uint16_t delay = 2*(_scanningParams.getInterval());
01149 #ifdef AST_FOR_MBED_OS
01150     if(_connecting) {
01151       minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay));
01152     } else {
01153       minar::Scheduler::postCallback(radioScanning).delay(minar::milliseconds(delay));
01154     }
01155 #else
01156     Clock_Wait(delay);
01157     if(_connecting) {
01158       makeConnection();
01159     } else {
01160       radioScanning();
01161     }
01162 #endif
01163     break;
01164   }
01165 }
01166 
01167 ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams)
01168 {
01169   
01170   tBleStatus ret = BLE_STATUS_SUCCESS;
01171   
01172   PRINTF("Scanning...\n\r");
01173   
01174   // We received a start scan request from the application level.
01175   // If we are on X-NUCLEO-IDB04A1 (playing a single role at time),
01176   // we need to re-init our expansion board to specify the GAP CENTRAL ROLE
01177   if(!btle_reinited) {
01178     btle_init(isSetAddress, GAP_CENTRAL_ROLE_IDB04A1);
01179     btle_reinited = true;
01180     
01181     PRINTF("BTLE re-init\n\r");
01182   }
01183   
01184   ret = aci_gap_start_general_discovery_proc(scanningParams.getInterval(),
01185                          scanningParams.getWindow(),
01186                          addr_type,
01187                          1); // 1 to filter duplicates
01188   
01189   if (ret != BLE_STATUS_SUCCESS) {
01190     printf("Start Discovery Procedure failed (0x%02X)\n\r", ret);
01191     return BLE_ERROR_UNSPECIFIED; 
01192   } else {
01193     PRINTF("Discovery Procedure Started\n");
01194     _scanning = true;
01195     return BLE_ERROR_NONE; 
01196   }
01197 }
01198 
01199 ble_error_t BlueNRGGap::stopScan() {
01200   tBleStatus ret = BLE_STATUS_SUCCESS;
01201   
01202   ret = aci_gap_terminate_gap_procedure(GENERAL_DISCOVERY_PROCEDURE);
01203   
01204   if (ret != BLE_STATUS_SUCCESS) {
01205     printf("GAP Terminate Gap Procedure failed\n");
01206     return BLE_ERROR_UNSPECIFIED; 
01207   } else {
01208     PRINTF("Discovery Procedure Terminated\n");
01209     return BLE_ERROR_NONE; 
01210   }
01211 }
01212 
01213 /**************************************************************************/
01214 /*!
01215     @brief  set Tx power level
01216     @param[in] txPower Transmission Power level
01217     @returns    ble_error_t
01218 */
01219 /**************************************************************************/
01220 ble_error_t BlueNRGGap::setTxPower(int8_t txPower)
01221 {
01222     tBleStatus ret;
01223     
01224     int8_t enHighPower = 0;
01225     int8_t paLevel = 0;
01226 
01227     int8_t dbmActuallySet = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel);
01228 
01229 #ifndef DEBUG
01230     /* avoid compiler warnings about unused variables */
01231     (void)dbmActuallySet;
01232 #endif
01233     
01234     PRINTF("txPower=%d, dbmActuallySet=%d\n\r", txPower, dbmActuallySet);
01235     PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);                    
01236     ret = aci_hal_set_tx_power_level(enHighPower, paLevel);
01237     if(ret!=BLE_STATUS_SUCCESS) {
01238       return BLE_ERROR_UNSPECIFIED;
01239     }
01240 
01241     return BLE_ERROR_NONE;
01242 }
01243 
01244 /**************************************************************************/
01245 /*!
01246     @brief  get permitted Tx power values
01247     @param[in] values pointer to pointer to permitted power values
01248     @param[in] num number of values   
01249 */
01250 /**************************************************************************/
01251 void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
01252     static const int8_t permittedTxValues[] = {
01253         -18, -14, -11, -8, -4, -1, 1, 5, -15, -11, -8, -5, -2, 1, 4, 8
01254     };
01255 
01256     *valueArrayPP = permittedTxValues;
01257     *countP = sizeof(permittedTxValues) / sizeof(int8_t);
01258 }
01259 
01260 ble_error_t BlueNRGGap::createConnection ()
01261 {
01262   tBleStatus ret;
01263   
01264   /*
01265     Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, 
01266     Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max    
01267   */
01268   ret = aci_gap_create_connection(SCAN_P,
01269                   SCAN_L,
01270                   PUBLIC_ADDR,
01271                   (unsigned char*)_peerAddr,
01272                   PUBLIC_ADDR,
01273                   CONN_P1, CONN_P2, 0,
01274                   SUPERV_TIMEOUT, CONN_L1 , CONN_L2);
01275 
01276   _connecting = false;
01277   
01278   if (ret != BLE_STATUS_SUCCESS) {
01279     printf("Error while starting connection (ret=0x%02X).\n\r", ret);
01280     return BLE_ERROR_UNSPECIFIED;
01281   } else {
01282     PRINTF("Connection started.\n");
01283     return BLE_ERROR_NONE;
01284   }
01285 }
01286 
01287 ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr,
01288                                  Gap::AddressType_t peerAddrType,
01289                                  const ConnectionParams_t *connectionParams,
01290                                  const GapScanningParams *scanParams)
01291 {
01292   /* avoid compiler warnings about unused variables */
01293   (void)peerAddrType;
01294   (void)connectionParams;
01295   (void)scanParams;
01296 
01297     // Save the peer address
01298   for(int i=0; i<BDADDR_SIZE; i++) {
01299     _peerAddr[i] = peerAddr[i];
01300   }
01301 
01302   _connecting = true;
01303 
01304   if(_scanning) {
01305     stopScan();
01306   } else {
01307     PRINTF("Calling createConnection from connect()\n\r");
01308     return createConnection();
01309   }
01310   
01311   return BLE_ERROR_NONE;
01312 }