Devchannel Team / X_NUCLEO_IDB0XA1

Dependents:   Hello_BLE F446RE-BLE

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 
00048 //Local Variables
00049 //const char *local_name = NULL;
00050 //uint8_t local_name_length = 0;
00051 const uint8_t *scan_response_payload = NULL;
00052 uint8_t scan_rsp_length = 0;
00053 
00054 uint32_t advtInterval = BLUENRG_GAP_ADV_INTERVAL_MAX;
00055 
00056 /*
00057  * Utility to process GAP specific events (e.g., Advertising timeout)
00058  */
00059 void BlueNRGGap::Process(void)
00060 {    
00061     if(AdvToFlag) {
00062         stopAdvertising();
00063     }
00064 
00065 }
00066 
00067 /**************************************************************************/
00068 /*!
00069     @brief  Sets the advertising parameters and payload for the device. 
00070             Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API
00071 
00072     @params[in] advData
00073                 The primary advertising data payload
00074     @params[in] scanResponse
00075                 The optional Scan Response payload if the advertising
00076                 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
00077                 in \ref GapAdveritinngParams
00078 
00079     @returns    \ref ble_error_t
00080 
00081     @retval     BLE_ERROR_NONE
00082                 Everything executed properly
00083 
00084     @retval     BLE_ERROR_BUFFER_OVERFLOW
00085                 The proposed action would cause a buffer overflow.  All
00086                 advertising payloads must be <= 31 bytes, for example.
00087 
00088     @retval     BLE_ERROR_NOT_IMPLEMENTED
00089                 A feature was requested that is not yet supported in the
00090                 nRF51 firmware or hardware.
00091 
00092     @retval     BLE_ERROR_PARAM_OUT_OF_RANGE
00093                 One of the proposed values is outside the valid range.
00094 
00095     @section EXAMPLE
00096 
00097     @code
00098 
00099     @endcode
00100 */
00101 /**************************************************************************/
00102 ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
00103 { 
00104     DEBUG("BlueNRGGap::setAdvertisingData\n\r");
00105     /* Make sure we don't exceed the advertising payload length */
00106     if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
00107         return BLE_ERROR_BUFFER_OVERFLOW;
00108     }
00109 
00110     /* Make sure we have a payload! */
00111     if (advData.getPayloadLen() <= 0) {
00112         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00113     } else { 
00114         PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());        
00115         for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) {                  
00116             loadPtr.getUnitAtIndex(index);
00117 
00118             DEBUG("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr()));
00119             DEBUG("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()));                  
00120             
00121             switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) {
00122             case GapAdvertisingData::FLAGS:                              /* ref *Flags */                     
00123                 {
00124                 DEBUG("Advertising type: FLAGS\n\r");
00125                 //Check if Flags are OK. BlueNRG only supports LE Mode.
00126                 uint8_t *flags = loadPtr.getUnitAtIndex(index).getDataPtr();
00127                 if((*flags & GapAdvertisingData::BREDR_NOT_SUPPORTED) != GapAdvertisingData::BREDR_NOT_SUPPORTED) {
00128                     DEBUG("BlueNRG does not support BR/EDR Mode");
00129                     return BLE_ERROR_PARAM_OUT_OF_RANGE;
00130                 }
00131                 
00132                 break;
00133                 }
00134             case GapAdvertisingData::INCOMPLETE_LIST_16BIT_SERVICE_IDS:  /**< Incomplete list of 16-bit Service IDs */
00135             case GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS:    /**< Complete list of 16-bit Service IDs */
00136                 {
00137                 DEBUG("Advertising type: INCOMPLETE_LIST_16BIT_SERVICE_IDS/COMPLETE_LIST_16BIT_SERVICE_IDS\n\r");
00138                 
00139                 uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;
00140                 // The total lenght should include the Data Type Value
00141                 if(buffSize>UUID_BUFFER_SIZE-1) {
00142                     return BLE_ERROR_PARAM_OUT_OF_RANGE;
00143                 }
00144                 
00145                 servUuidlength = buffSize+1; // +1 to include the Data Type Value
00146                 servUuidData[0] = (uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()); //Data Type Value
00147                 
00148                 DEBUG("servUuidlength=%d servUuidData[0]=%d buffSize=%d\n\r", servUuidlength, servUuidData[0], buffSize);
00149                 // Save the Service UUID list just after the Data Type Value field
00150                 memcpy(servUuidData+1, loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize);
00151                 
00152                 for(unsigned i=0; i<servUuidlength; i++) {
00153                     DEBUG("servUuidData[%d] = 0x%x\n\r", i, servUuidData[i]);
00154                 }
00155                 
00156                 for(unsigned i=0; i<buffSize; i++) {
00157                     DEBUG("loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
00158                 }
00159 
00160                 break;
00161                 }
00162             case GapAdvertisingData::INCOMPLETE_LIST_32BIT_SERVICE_IDS:  /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
00163                 {
00164                 DEBUG("Advertising type: INCOMPLETE_LIST_32BIT_SERVICE_IDS\n\r");
00165                 return BLE_ERROR_NOT_IMPLEMENTED;
00166                 }
00167             case GapAdvertisingData::COMPLETE_LIST_32BIT_SERVICE_IDS:    /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
00168                 {
00169                 DEBUG("Advertising type: COMPLETE_LIST_32BIT_SERVICE_IDS\n\r");
00170                 return BLE_ERROR_NOT_IMPLEMENTED;
00171                 }
00172             case GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS: /**< Incomplete list of 128-bit Service IDs */
00173                 {
00174                 DEBUG("Advertising type: INCOMPLETE_LIST_128BIT_SERVICE_IDS\n\r");
00175                 return BLE_ERROR_NOT_IMPLEMENTED;
00176                 }
00177             case GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS:   /**< Complete list of 128-bit Service IDs */
00178                 {
00179                 DEBUG("Advertising type: COMPLETE_LIST_128BIT_SERVICE_IDS\n\r");
00180                 return BLE_ERROR_NOT_IMPLEMENTED;
00181                 }
00182             case GapAdvertisingData::SHORTENED_LOCAL_NAME:               /**< Shortened Local Name */
00183                 {
00184                 break;
00185                 }
00186             case GapAdvertisingData::COMPLETE_LOCAL_NAME:                /**< Complete Local Name */
00187                 {
00188                 DEBUG("Advertising type: COMPLETE_LOCAL_NAME\n\r");
00189                 loadPtr.getUnitAtIndex(index).printDataAsString();       
00190                 local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;                        
00191                 local_name = (uint8_t*)loadPtr.getUnitAtIndex(index).getAdTypePtr();
00192                 DEBUG("Advertising type: COMPLETE_LOCAL_NAME local_name=%s\n\r", local_name);
00193                 //COMPLETE_LOCAL_NAME is only advertising device name. Gatt Device Name is not the same.(Must be set right after GAP/GATT init?)
00194                 
00195                 DEBUG("device_name length=%d\n\r", local_name_length);                                    
00196                 break;
00197                 }
00198             case GapAdvertisingData::TX_POWER_LEVEL:                     /**< TX Power Level (in dBm) */
00199                 {
00200                 DEBUG("Advertising type: TX_POWER_LEVEL\n\r");     
00201                 int8_t enHighPower = 0;
00202                 int8_t paLevel = 0;
00203 #if NEED_CONSOLE_OUTPUT
00204                 int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr();
00205                 int8_t dbmActuallySet = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel);
00206 #endif
00207                 DEBUG("dbm=%d, dbmActuallySet=%d\n\r", dbm, dbmActuallySet);
00208                 DEBUG("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);                    
00209                 aci_hal_set_tx_power_level(enHighPower, paLevel);
00210                 break;
00211                 }
00212             case GapAdvertisingData::DEVICE_ID:                          /**< Device ID */
00213                 {
00214                 break;
00215                 }
00216             case GapAdvertisingData::SLAVE_CONNECTION_INTERVAL_RANGE:    /**< Slave :Connection Interval Range */
00217                 {
00218                 break;
00219                 }
00220             case GapAdvertisingData::SERVICE_DATA:                       /**< Service Data */
00221                 {
00222                 DEBUG("Advertising type: SERVICE_DATA\n\r");
00223                 uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;
00224                 DEBUG("Advertising type: SERVICE_DATA (buffSize=%d)\n\r", buffSize);
00225                 // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte
00226                 if(buffSize>ADV_DATA_MAX_SIZE-2) {
00227                     return BLE_ERROR_PARAM_OUT_OF_RANGE;
00228                 }
00229                 for(int i=0; i<buffSize+1; i++) {
00230                     DEBUG("Advertising type: SERVICE_DATA loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
00231                 }
00232                 AdvLen = buffSize+2; // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte
00233                 AdvData[0] = buffSize+1; // the fisrt byte is the data buffer size (type+data)
00234                 AdvData[1] = AD_TYPE_SERVICE_DATA;
00235                 memcpy(AdvData+2, loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize);
00236                 break;
00237                 }
00238             case GapAdvertisingData::APPEARANCE:   
00239                 {
00240                 /* 
00241                     Tested with GapAdvertisingData::GENERIC_PHONE. 
00242                     for other appearances BLE Scanner android app is not behaving properly 
00243                     */
00244                 DEBUG("Advertising type: APPEARANCE\n\r");
00245                 const char *deviceAppearance = NULL;                    
00246                 deviceAppearance = (const char*)loadPtr.getUnitAtIndex(index).getDataPtr();  // to be set later when startAdvertising() is called
00247                 
00248 #if NEED_CONSOLE_OUTPUT
00249                 uint8_t Appearance[2] = {0, 0};
00250                 uint16_t devP = (uint16_t)*deviceAppearance;
00251                 STORE_LE_16(Appearance, (uint16_t)devP);
00252 #endif
00253                 
00254                 DEBUG("input: deviceAppearance= 0x%x 0x%x..., strlen(deviceAppearance)=%d\n\r", Appearance[1], Appearance[0], (uint8_t)*loadPtr.getUnitAtIndex(index).getLenPtr()-1);         /**< \ref Appearance */
00255                 
00256                 aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (uint8_t *)deviceAppearance);//not using array Appearance[2]
00257                 break;
00258                 }
00259             case GapAdvertisingData::ADVERTISING_INTERVAL:               /**< Advertising Interval */
00260                 {
00261                 DEBUG("Advertising type: ADVERTISING_INTERVAL\n\r");
00262                 advtInterval = (uint16_t)(*loadPtr.getUnitAtIndex(index).getDataPtr());
00263                 DEBUG("advtInterval=%d\n\r", advtInterval);
00264                 break;
00265                 }
00266             case GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA:        /**< Manufacturer Specific Data */                                
00267                 {
00268                 break;
00269                 }
00270                 
00271             }          
00272         }
00273         //Set the SCAN_RSP Payload
00274         scan_response_payload = scanResponse.getPayload();
00275         scan_rsp_length = scanResponse.getPayloadLen();
00276     }
00277     return BLE_ERROR_NONE;
00278 }
00279 
00280 /*
00281  * Utility to set ADV timeout flag
00282  */
00283 void BlueNRGGap::setAdvToFlag(void) {
00284     AdvToFlag = true;
00285 }
00286 
00287 /*
00288  * ADV timeout callback
00289  */   
00290 static void advTimeoutCB(void)
00291 {
00292     Gap::GapState_t state;
00293     
00294     state = BlueNRGGap::getInstance().getState();
00295     if (state.advertising == 1) {
00296         
00297         BlueNRGGap::getInstance().setAdvToFlag();
00298         
00299         Timeout t = BlueNRGGap::getInstance().getAdvTimeout();
00300         t.detach(); /* disable the callback from the timeout */
00301 
00302     }
00303 }
00304 
00305     
00306 /**************************************************************************/
00307 /*!
00308     @brief  Starts the BLE HW, initialising any services that were
00309             added before this function was called.
00310     
00311     @param[in]  params
00312                 Basic advertising details, including the advertising
00313                 delay, timeout and how the device should be advertised
00314                 
00315     @note   All services must be added before calling this function!
00316 
00317     @returns    ble_error_t
00318 
00319     @retval     BLE_ERROR_NONE
00320                 Everything executed properly
00321 
00322     @section EXAMPLE
00323 
00324     @code
00325 
00326     @endcode
00327 */
00328 /**************************************************************************/
00329 
00330 ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams &params)
00331 {      
00332     /* Make sure we support the advertising type */
00333     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
00334         /* ToDo: This requires a propery security implementation, etc. */
00335         return BLE_ERROR_NOT_IMPLEMENTED;
00336     }
00337 
00338     /* Check interval range */
00339     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
00340         /* Min delay is slightly longer for unconnectable devices */
00341         if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
00342                 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
00343             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00344         }
00345     } else {
00346         if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
00347                 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
00348             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00349         }
00350     }
00351 
00352     /* Check timeout is zero for Connectable Directed */
00353     if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
00354         /* Timeout must be 0 with this type, although we'll never get here */
00355         /* since this isn't implemented yet anyway */
00356         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00357     }
00358 
00359     /* Check timeout for other advertising types */
00360     if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
00361             (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
00362         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00363     }
00364 
00365     //tBleStatus ret;
00366     //const LongUUIDBytes_t HRM_SERVICE_UUID_128 = {0x18, 0x0D};
00367     /* set scan response data */
00368     hci_le_set_scan_resp_data(scan_rsp_length, scan_response_payload); /*int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]);*/
00369 
00370     /*aci_gap_set_discoverable(Advertising_Event_Type, Adv_min_intvl, Adv_Max_Intvl, Addr_Type, Adv_Filter_Policy,
00371                         Local_Name_Length, local_name, service_uuid_length, service_uuid_list, Slave_conn_intvl_min, Slave_conn_intvl_max);*/
00372     /*LINK_LAYER.H DESCRIBES THE ADVERTISING TYPES*/ 
00373 
00374     char* name = NULL;
00375     uint8_t nameLen = 0; 
00376     if(local_name!=NULL) {
00377         name = (char*)local_name;
00378         DEBUG("name=%s\n\r", name); 
00379         nameLen = local_name_length;
00380     } else {
00381         char str[] = "ST_BLE_DEV";
00382         name = new char[strlen(str)+1];
00383         name[0] = AD_TYPE_COMPLETE_LOCAL_NAME;
00384         strcpy(name+1, str);
00385         nameLen = strlen(name);
00386         DEBUG("nameLen=%d\n\r", nameLen);
00387         DEBUG("name=%s\n\r", name);      
00388     }  
00389 
00390     advtInterval = params.getIntervalInADVUnits(); // set advtInterval in case it is not already set by user application  
00391     ret = aci_gap_set_discoverable(params.getAdvertisingType(), // Advertising_Event_Type                                
00392         advtInterval,   // Adv_Interval_Min
00393         advtInterval,   // Adv_Interval_Max
00394         PUBLIC_ADDR, // Address_Type 
00395         NO_WHITE_LIST_USE,  // Adv_Filter_Policy
00396         nameLen, //local_name_length, // Local_Name_Length
00397         (const char*)name, //local_name, // Local_Name
00398         servUuidlength,  //Service_Uuid_Length
00399         servUuidData, //Service_Uuid_List
00400         0, // Slave_Conn_Interval_Min
00401         0);  // Slave_Conn_Interval_Max
00402 
00403     
00404     DEBUG("!!!setting discoverable (servUuidlength=0x%x)\n", servUuidlength);
00405     if(BLE_STATUS_SUCCESS!=ret) {
00406        DEBUG("error occurred while setting discoverable (ret=0x%x)\n", ret);
00407        return BLE_ERROR_PARAM_OUT_OF_RANGE;  // no other suitable error code is available
00408     }
00409 
00410     // Before updating the ADV data, delete COMPLETE_LOCAL_NAME and TX_POWER_LEVEL fields (if present)
00411     if(AdvLen>0) {
00412       if(name!=NULL) {
00413         DEBUG("!!!calling aci_gap_delete_ad_type AD_TYPE_COMPLETE_LOCAL_NAME!!!\n");
00414         ret = aci_gap_delete_ad_type(AD_TYPE_COMPLETE_LOCAL_NAME);
00415         if (ret != BLE_STATUS_SUCCESS){
00416           DEBUG("aci_gap_delete_ad_type failed return=%d\n", ret);
00417           return BLE_ERROR_PARAM_OUT_OF_RANGE;
00418         }
00419       }
00420 
00421       if(txPowerAdType) {
00422         DEBUG("!!!calling aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL)!!!\n", AdvLen);
00423         ret = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL);
00424         if (ret != BLE_STATUS_SUCCESS){
00425           DEBUG("aci_gap_delete_ad_type failed return=%d\n", ret);
00426           return BLE_ERROR_PARAM_OUT_OF_RANGE;
00427         }
00428       }
00429    
00430       ret = aci_gap_update_adv_data(AdvLen, AdvData);
00431       if(BLE_STATUS_SUCCESS!=ret) {
00432         DEBUG("error occurred while adding adv data (ret=0x%x)\n", ret);
00433         return BLE_ERROR_PARAM_OUT_OF_RANGE;  // no other suitable error code is available
00434       }
00435       
00436     }
00437 
00438     state.advertising = 1;
00439 
00440     AdvToFlag = false;
00441     if(params.getTimeout() != 0) {
00442         DEBUG("!!! attaching to!!!\n");
00443         advTimeout.attach(advTimeoutCB, params.getTimeout());
00444     }
00445     
00446     return BLE_ERROR_NONE;
00447 }
00448 
00449 /**************************************************************************/
00450 /*!
00451     @brief  Stops the BLE HW and disconnects from any devices
00452 
00453     @returns    ble_error_t
00454 
00455     @retval     BLE_ERROR_NONE
00456                 Everything executed properly
00457 
00458     @section EXAMPLE
00459 
00460     @code
00461 
00462     @endcode
00463 */
00464 /**************************************************************************/
00465 ble_error_t BlueNRGGap::stopAdvertising(void)
00466 {
00467     tBleStatus ret;
00468     
00469     if(state.advertising == 1) {
00470         //Set non-discoverable to stop advertising
00471         ret = aci_gap_set_non_discoverable();
00472         
00473         if (ret != BLE_STATUS_SUCCESS){
00474             DEBUG("Error in stopping advertisement (ret=0x%x)!!\n\r", ret) ;
00475             return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value 
00476             //FIXME: Define Error values equivalent to BlueNRG Error Codes.
00477         }
00478         DEBUG("Advertisement stopped!!\n\r") ;
00479         //Set GapState_t::advertising state
00480         state.advertising = 0;
00481     }
00482     
00483     return BLE_ERROR_NONE;
00484 }
00485 
00486 /**************************************************************************/
00487 /*!
00488     @brief  Disconnects if we are connected to a central device
00489 
00490     @param[in]  reason
00491                 Disconnection Reason
00492                 
00493     @returns    ble_error_t
00494 
00495     @retval     BLE_ERROR_NONE
00496                 Everything executed properly
00497 
00498     @section EXAMPLE
00499 
00500     @code
00501 
00502     @endcode
00503 */
00504 /**************************************************************************/
00505 ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason)
00506 {
00507     tBleStatus ret;
00508     //For Reason codes check BlueTooth HCI Spec
00509     
00510     if(m_connectionHandle != BLE_CONN_HANDLE_INVALID) {
00511         ret = aci_gap_terminate(m_connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. 
00512 
00513         if (ret != BLE_STATUS_SUCCESS){
00514             DEBUG("Error in GAP termination!!\n\r") ;
00515             return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value 
00516             //FIXME: Define Error values equivalent to BlueNRG Error Codes.
00517         }
00518         
00519         //DEBUG("Disconnected from localhost!!\n\r") ;
00520         m_connectionHandle = BLE_CONN_HANDLE_INVALID;
00521     }
00522     
00523     return BLE_ERROR_NONE;
00524 }
00525 
00526 /**************************************************************************/
00527 /*!
00528     @brief  Disconnects if we are connected to a central device
00529 
00530     @param[in]  reason
00531                 Disconnection Reason
00532                 
00533     @returns    ble_error_t
00534 
00535     @retval     BLE_ERROR_NONE
00536                 Everything executed properly
00537 
00538     @section EXAMPLE
00539 
00540     @code
00541 
00542     @endcode
00543 */
00544 /**************************************************************************/
00545 ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason)
00546 {
00547     tBleStatus ret;
00548     //For Reason codes check BlueTooth HCI Spec
00549     
00550     if(connectionHandle != BLE_CONN_HANDLE_INVALID) {
00551         ret = aci_gap_terminate(connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. 
00552 
00553         if (ret != BLE_STATUS_SUCCESS){
00554             DEBUG("Error in GAP termination!!\n\r") ;
00555             return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value 
00556             //FIXME: Define Error values equivalent to BlueNRG Error Codes.
00557         }
00558         
00559         //DEBUG("Disconnected from localhost!!\n\r") ;
00560         m_connectionHandle = BLE_CONN_HANDLE_INVALID;
00561     }
00562     
00563     return BLE_ERROR_NONE;
00564 }
00565 
00566 /**************************************************************************/
00567 /*!
00568     @brief  Sets the 16-bit connection handle
00569     
00570     @param[in]  con_handle
00571                 Connection Handle which is set in the Gap Instance
00572                 
00573     @returns    void
00574 */
00575 /**************************************************************************/
00576 void BlueNRGGap::setConnectionHandle(uint16_t con_handle)
00577 {
00578     m_connectionHandle = con_handle;
00579 }
00580 
00581 /**************************************************************************/
00582 /*!
00583     @brief  Gets the 16-bit connection handle
00584     
00585     @param[in]  void
00586                 
00587     @returns    uint16_t
00588                 Connection Handle of the Gap Instance
00589 */
00590 /**************************************************************************/
00591 uint16_t BlueNRGGap::getConnectionHandle(void)
00592 {
00593     return m_connectionHandle;
00594 }
00595 
00596 /**************************************************************************/
00597 /*!
00598     @brief      Sets the BLE device address. SetAddress will reset the BLE
00599                 device and re-initialize BTLE. Will not start advertising.
00600 
00601     @param[in]  type
00602                 Type of Address
00603     
00604     @param[in]  address[6]
00605                 Value of the Address to be set
00606                 
00607     @returns    ble_error_t
00608 
00609     @section EXAMPLE
00610 
00611     @code
00612 
00613     @endcode
00614 */
00615 /**************************************************************************/
00616 ble_error_t BlueNRGGap::setAddress(addr_type_t type, const Address_t address)
00617 {
00618     //tBleStatus ret;
00619     
00620     if (type > ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) {
00621         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00622     }
00623     
00624     //copy address to bdAddr[6]
00625     for(int i=0; i<BDADDR_SIZE; i++) {
00626         bdaddr[i] = address[i];
00627         //DEBUG("i[%d]:0x%x\n\r",i,bdaddr[i]);
00628     }
00629     
00630     if(!isSetAddress) isSetAddress = true;
00631     
00632     //Re-Init the BTLE Device with SetAddress as true
00633     //if(BlueNRGDevice::getIsInitialized())//Re-init only initialization is already done
00634     // ANDREA
00635     //btle_init(isSetAddress, D11, D12, D3);
00636     
00637     //if (ret==BLE_STATUS_SUCCESS)
00638     return BLE_ERROR_NONE;
00639 }
00640 
00641 /**************************************************************************/
00642 /*!
00643     @brief      Returns boolean if the address of the device has been set
00644                 or not
00645                 
00646     @returns    bool
00647 
00648     @section EXAMPLE
00649 
00650     @code
00651 
00652     @endcode
00653 */
00654 /**************************************************************************/
00655 bool BlueNRGGap::getIsSetAddress() 
00656 {
00657     return isSetAddress;   
00658 }
00659 
00660 /**************************************************************************/
00661 /*!
00662     @brief      Returns the address of the device if set
00663 
00664     @returns    Pointer to the address if Address is set else NULL
00665 
00666     @section EXAMPLE
00667 
00668     @code
00669 
00670     @endcode
00671 */
00672 /**************************************************************************/
00673 ble_error_t BlueNRGGap::getAddress(AddressType_t *typeP, Address_t address) 
00674 {
00675     *typeP = Gap::ADDR_TYPE_PUBLIC;
00676     
00677     if(isSetAddress)
00678     {
00679         for(int i=0; i<BDADDR_SIZE; i++) {
00680             address[i] = bdaddr[i];
00681             //DEBUG("i[%d]:0x%x\n\r",i,bdaddr[i]);
00682         }
00683     }
00684         
00685     return BLE_ERROR_NONE;
00686 }
00687 
00688 /**************************************************************************/
00689 /*!
00690     @brief      obtains preferred connection params
00691 
00692     @returns    ble_error_t
00693 
00694     @section EXAMPLE
00695 
00696     @code
00697 
00698     @endcode
00699 */
00700 /**************************************************************************/
00701 ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) 
00702 {
00703     return BLE_ERROR_NONE;
00704 }
00705 
00706 
00707 /**************************************************************************/
00708 /*!
00709     @brief      sets preferred connection params
00710 
00711     @returns    ble_error_t
00712 
00713     @section EXAMPLE
00714 
00715     @code
00716 
00717     @endcode
00718 */
00719 /**************************************************************************/
00720 ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) 
00721 {
00722     return BLE_ERROR_NONE;
00723 }
00724 
00725 /**************************************************************************/
00726 /*!
00727     @brief      updates preferred connection params
00728 
00729     @returns    ble_error_t
00730 
00731     @section EXAMPLE
00732 
00733     @code
00734 
00735     @endcode
00736 */
00737 /**************************************************************************/
00738 ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params)
00739 {
00740     return BLE_ERROR_NONE;
00741 }
00742 
00743 /**************************************************************************/
00744 /*!
00745     @brief  Sets the Device Name Characteristic 
00746 
00747     @param[in]  deviceName
00748                 pointer to device name to be set
00749 
00750     @returns    ble_error_t
00751 
00752     @retval     BLE_ERROR_NONE
00753                 Everything executed properly
00754 
00755     @section EXAMPLE
00756 
00757     @code
00758 
00759     @endcode
00760 */
00761 /**************************************************************************/
00762 ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) 
00763 {
00764     int ret;
00765     uint8_t nameLen = 0;     
00766     
00767     DeviceName = (uint8_t *)deviceName;
00768     //DEBUG("SetDeviceName=%s\n\r", DeviceName);
00769     
00770     nameLen = strlen((const char*)DeviceName);
00771     //DEBUG("DeviceName Size=%d\n\r", nameLen); 
00772     
00773     ret = aci_gatt_update_char_value(g_gap_service_handle, 
00774     g_device_name_char_handle, 
00775     0, 
00776     nameLen, 
00777     (uint8_t *)DeviceName);
00778     
00779     if(ret){
00780         DEBUG("device set name failed\n\r");            
00781         return BLE_ERROR_PARAM_OUT_OF_RANGE;//TODO:Wrong error code
00782     }
00783 
00784     return BLE_ERROR_NONE;
00785 }
00786 
00787 /**************************************************************************/
00788 /*!
00789     @brief  Gets the Device Name Characteristic 
00790 
00791     @param[in]  deviceName
00792                 pointer to device name                 
00793 
00794     @param[in]  lengthP
00795                 pointer to device name length                
00796 
00797     @returns    ble_error_t
00798 
00799     @retval     BLE_ERROR_NONE
00800                 Everything executed properly
00801 
00802     @section EXAMPLE
00803 
00804     @code
00805 
00806     @endcode
00807 */
00808 /**************************************************************************/
00809 ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) 
00810 {   
00811     //int ret;
00812     
00813     if(DeviceName==NULL) 
00814     return BLE_ERROR_PARAM_OUT_OF_RANGE;
00815     
00816     strcpy((char*)deviceName, (const char*)DeviceName);
00817     //DEBUG("GetDeviceName=%s\n\r", deviceName);
00818     
00819     *lengthP = strlen((const char*)DeviceName);
00820     //DEBUG("DeviceName Size=%d\n\r", *lengthP); 
00821     
00822     return BLE_ERROR_NONE;
00823 }
00824 
00825 /**************************************************************************/
00826 /*!
00827     @brief  Sets the Device Appearance Characteristic 
00828 
00829     @param[in]  appearance
00830                 device appearance      
00831 
00832     @returns    ble_error_t
00833 
00834     @retval     BLE_ERROR_NONE
00835                 Everything executed properly
00836 
00837     @section EXAMPLE
00838 
00839     @code
00840 
00841     @endcode
00842 */
00843 /**************************************************************************/
00844 ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance)
00845 {
00846     /* 
00847     Tested with GapAdvertisingData::GENERIC_PHONE. 
00848     for other appearances BLE Scanner android app is not behaving properly 
00849     */
00850     //char deviceAppearance[2];   
00851     STORE_LE_16(deviceAppearance, appearance);                 
00852     DEBUG("input: incoming = %d deviceAppearance= 0x%x 0x%x\n\r", appearance, deviceAppearance[1], deviceAppearance[0]);
00853     
00854     aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (uint8_t *)deviceAppearance);
00855     
00856     return BLE_ERROR_NONE;    
00857 }
00858 
00859 /**************************************************************************/
00860 /*!
00861     @brief  Gets the Device Appearance Characteristic
00862 
00863     @param[in]  appearance
00864                 pointer to device appearance value      
00865 
00866     @returns    ble_error_t
00867 
00868     @retval     BLE_ERROR_NONE
00869                 Everything executed properly
00870 
00871     @section EXAMPLE
00872 
00873     @code
00874 
00875     @endcode
00876 */
00877 /**************************************************************************/
00878 ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
00879 {
00880     uint16_t devP;
00881     if(!appearanceP) return BLE_ERROR_PARAM_OUT_OF_RANGE;
00882     devP = ((uint16_t)(0x0000|deviceAppearance[0])) | (((uint16_t)(0x0000|deviceAppearance[1]))<<8);
00883     strcpy((char*)appearanceP, (const char*)&devP);
00884     
00885     return BLE_ERROR_NONE;    
00886 }
00887 
00888 /**************************************************************************/
00889 /*!
00890     @brief  Gets the value of maximum advertising interval in ms
00891 
00892     @returns    uint16_t
00893 
00894     @retval     value of maximum advertising interval in ms
00895                 
00896     @section EXAMPLE
00897 
00898     @code
00899 
00900     @endcode
00901 */
00902 /**************************************************************************/
00903 uint16_t BlueNRGGap::getMaxAdvertisingInterval(void) const  {
00904     return advtInterval;
00905 } 
00906 
00907 
00908 /**************************************************************************/
00909 /*!
00910     @brief  Gets the value of minimum advertising interval in ms
00911 
00912     @returns    uint16_t
00913 
00914     @retval     value of minimum advertising interval in ms
00915                 
00916     @section EXAMPLE
00917 
00918     @code
00919 
00920     @endcode
00921 */
00922 /**************************************************************************/
00923 uint16_t BlueNRGGap::getMinAdvertisingInterval(void) const {    
00924     return 0;    // minimum Advertising interval is 0
00925 }
00926 
00927 /**************************************************************************/
00928 /*!
00929     @brief  Gets the value of minimum non connectable advertising interval in ms
00930 
00931     @returns    uint16_t
00932 
00933     @retval     value of minimum non connectable advertising interval in ms
00934                 
00935     @section EXAMPLE
00936 
00937     @code
00938 
00939     @endcode
00940 */
00941 /**************************************************************************/
00942 uint16_t BlueNRGGap::getMinNonConnectableAdvertisingInterval(void) const {     
00943     return BLE_GAP_ADV_NONCON_INTERVAL_MIN;    
00944 }
00945 
00946 // ANDREA
00947 ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) {
00948     // Empty by now
00949     return BLE_ERROR_NONE; 
00950 }
00951 
00952 ble_error_t BlueNRGGap::stopScan() {
00953     // Empty by now
00954     return BLE_ERROR_NONE; 
00955 }
00956 
00957 /**************************************************************************/
00958 /*!
00959     @brief  set Tx power level
00960     @param[in] txPower Transmission Power level
00961     @returns    ble_error_t
00962 */
00963 /**************************************************************************/
00964 ble_error_t BlueNRGGap::setTxPower(int8_t txPower)
00965 {
00966     tBleStatus ret;
00967     
00968     int8_t enHighPower = 0;
00969     int8_t paLevel = 0;    
00970 #if NEED_CONSOLE_OUTPUT
00971     int8_t dbmActuallySet = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel);
00972 #endif
00973     
00974     DEBUG("txPower=%d, dbmActuallySet=%d\n\r", txPower, dbmActuallySet);
00975     DEBUG("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);                    
00976     ret = aci_hal_set_tx_power_level(enHighPower, paLevel);
00977     if(ret!=BLE_STATUS_SUCCESS) {
00978       return BLE_ERROR_UNSPECIFIED;
00979     }
00980     
00981     txPowerAdType = true;
00982     return BLE_ERROR_NONE;
00983 }
00984 
00985 /**************************************************************************/
00986 /*!
00987     @brief  get permitted Tx power values
00988     @param[in] values pointer to pointer to permitted power values
00989     @param[in] num number of values   
00990 */
00991 /**************************************************************************/
00992 void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
00993     static const int8_t permittedTxValues[] = {
00994         -18, -14, -11, -8, -4, -1, 1, 5, -15, -11, -8, -5, -2, 1, 4, 8
00995     };
00996 
00997     *valueArrayPP = permittedTxValues;
00998     *countP = sizeof(permittedTxValues) / sizeof(int8_t);
00999 }