Robotique FIP / Mbed 2 deprecated FIP_REV1

Dependencies:   HC_SR04_Ultrasonic_Library Servo mbed

Fork of FIP_REV1 by Robotique FIP

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BlueNRGGap.cpp Source File

BlueNRGGap.cpp

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 #include "BlueNRGDevice.h"
00018 #include "mbed.h"
00019 #include "Payload.h"
00020 #include "Utils.h"
00021 
00022 //Local Variables
00023 const char *local_name = NULL;
00024 uint8_t local_name_length = 0;
00025 const uint8_t *scan_response_payload = NULL;
00026 uint8_t scan_rsp_length = 0;
00027 uint8_t servUuidlength = 0;
00028 uint8_t* servUuidData = NULL;
00029 
00030 uint32_t advtInterval = 0;
00031 
00032 /**************************************************************************/
00033 /*!
00034     @brief  Sets the advertising parameters and payload for the device. 
00035             Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API
00036 
00037     @param[in]  params
00038                 Basic advertising details, including the advertising
00039                 delay, timeout and how the device should be advertised
00040     @params[in] advData
00041                 The primary advertising data payload
00042     @params[in] scanResponse
00043                 The optional Scan Response payload if the advertising
00044                 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
00045                 in \ref GapAdveritinngParams
00046 
00047     @returns    \ref ble_error_t
00048 
00049     @retval     BLE_ERROR_NONE
00050                 Everything executed properly
00051 
00052     @retval     BLE_ERROR_BUFFER_OVERFLOW
00053                 The proposed action would cause a buffer overflow.  All
00054                 advertising payloads must be <= 31 bytes, for example.
00055 
00056     @retval     BLE_ERROR_NOT_IMPLEMENTED
00057                 A feature was requested that is not yet supported in the
00058                 nRF51 firmware or hardware.
00059 
00060     @retval     BLE_ERROR_PARAM_OUT_OF_RANGE
00061                 One of the proposed values is outside the valid range.
00062 
00063     @section EXAMPLE
00064 
00065     @code
00066 
00067     @endcode
00068 */
00069 /**************************************************************************/
00070 ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
00071 { 
00072     DEBUG("BlueNRGGap::setAdvertisingData\n\r");
00073     /* Make sure we don't exceed the advertising payload length */
00074     if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
00075         return BLE_ERROR_BUFFER_OVERFLOW;
00076     }
00077 
00078     /* Make sure we have a payload! */
00079     if (advData.getPayloadLen() <= 0) {
00080         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00081     } else { 
00082         PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());        
00083         for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) {                  
00084             PayloadUnit unit = loadPtr.getUnitAtIndex(index);
00085 
00086             DEBUG("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr()));
00087             DEBUG("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()));      
00088       
00089         #if 0                
00090 
00091             int err = aci_gap_update_adv_data(*loadPtr.getUnitAtIndex(index).getLenPtr(), loadPtr.getUnitAtIndex(index).getAdTypePtr());            
00092             if(BLE_STATUS_SUCCESS!=err) {
00093                 DEBUG("error occurred while adding adv data\n\r");
00094                 return BLE_ERROR_PARAM_OUT_OF_RANGE;  // no other suitable error code is available
00095                 DEBUG("error occurred while adding adv data for Adv type 0x%x, errCode = 0x%x\n", *loadPtr.getUnitAtIndex(index).getAdTypePtr(), err);
00096                 //return BLE_ERROR_PARAM_OUT_OF_RANGE;  // no other suitable error code is available
00097                }
00098         #endif
00099             //UnitPayload unitLoad = load.getPayLoadAtIndex(index);
00100             switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) {
00101                 case GapAdvertisingData::FLAGS:                              /* ref *Flags */                     
00102                 //Check if Flags are OK. BlueNRG only supports LE Mode.
00103                 uint8_t *flags = loadPtr.getUnitAtIndex(index).getDataPtr();
00104                 if((*flags & GapAdvertisingData::BREDR_NOT_SUPPORTED) != GapAdvertisingData::BREDR_NOT_SUPPORTED) {
00105                         DEBUG("BlueNRG does not support BR/EDR Mode");
00106                         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00107                      }
00108                 
00109                 break;
00110                 case GapAdvertisingData::INCOMPLETE_LIST_16BIT_SERVICE_IDS:  /**< Incomplete list of 16-bit Service IDs */
00111                 break;
00112                 case GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS:    /**< Complete list of 16-bit Service IDs */
00113                     DEBUG("Advertising type: COMPLETE_LIST_16BIT_SERVICE_IDS\n\r");
00114                     DEBUG("Advertising type: COMPLETE_LIST_16BIT_SERVICE_IDS\n");
00115                     #if 0
00116                     int err = aci_gap_update_adv_data(*loadPtr.getUnitAtIndex(index).getLenPtr(), loadPtr.getUnitAtIndex(index).getAdTypePtr());            
00117                     if(BLE_STATUS_SUCCESS!=err) {
00118                         DEBUG("error occurred while adding adv data\n");
00119                         return BLE_ERROR_PARAM_OUT_OF_RANGE;  // no other suitable error code is available
00120                         }
00121                     #endif
00122                     break;
00123                 case GapAdvertisingData::INCOMPLETE_LIST_32BIT_SERVICE_IDS:  /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
00124                 break;
00125                 case GapAdvertisingData::COMPLETE_LIST_32BIT_SERVICE_IDS:    /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
00126                 break;
00127                 case GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS: /**< Incomplete list of 128-bit Service IDs */
00128                 break;
00129                 case GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS:   /**< Complete list of 128-bit Service IDs */
00130                 break;
00131                 case GapAdvertisingData::SHORTENED_LOCAL_NAME:               /**< Shortened Local Name */
00132                 break;
00133                 case GapAdvertisingData::COMPLETE_LOCAL_NAME:                /**< Complete Local Name */
00134                     DEBUG("Advertising type: COMPLETE_LOCAL_NAME\n\r");
00135                     loadPtr.getUnitAtIndex(index).printDataAsString();       
00136                     local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;                        
00137                     local_name = (const char*)loadPtr.getUnitAtIndex(index).getAdTypePtr();  
00138                     //for(int i=0; i<local_name_length; i++) DEBUG("\n%c", local_name[i]);
00139                     /*aci_gatt_update_char_value(g_gap_service_handle, 
00140                                                 g_device_name_char_handle, 
00141                                                 0, 
00142                                                 local_name_length, 
00143                                                 (tHalUint8 *)local_name);*/
00144                     //COMPLETE_LOCAL_NAME is only advertising device name. Gatt Device Name is not the same.(Must be set right after GAP/GATT init?)
00145 
00146                             
00147                     DEBUG("device_name length=%d\n\r", local_name_length);                                    
00148                     break;
00149                 
00150                 case GapAdvertisingData::TX_POWER_LEVEL:                     /**< TX Power Level (in dBm) */
00151                     DEBUG("Advertising type: TX_POWER_LEVEL\n\r");     
00152                     int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr();
00153                     int8_t enHighPower = 0;
00154                     int8_t paLevel = 0;
00155                     int8_t dbmActuallySet = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel);
00156                     DEBUG("dbm=%d, dbmActuallySet=%d\n\r", dbm, dbmActuallySet);
00157                     DEBUG("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);                    
00158                     aci_hal_set_tx_power_level(enHighPower, paLevel);
00159                     break;
00160                 case GapAdvertisingData::DEVICE_ID:                          /**< Device ID */
00161                 break;
00162                 case GapAdvertisingData::SLAVE_CONNECTION_INTERVAL_RANGE:    /**< Slave :Connection Interval Range */
00163                 break;
00164                 case GapAdvertisingData::SERVICE_DATA:                       /**< Service Data */
00165                 break;
00166                 case GapAdvertisingData::APPEARANCE:   
00167                     /* 
00168                     Tested with GapAdvertisingData::GENERIC_PHONE. 
00169                     for other appearances BLE Scanner android app is not behaving properly 
00170                     */
00171                     DEBUG("Advertising type: APPEARANCE\n\r");
00172                     const char *deviceAppearance = NULL;                    
00173                     deviceAppearance = (const char*)loadPtr.getUnitAtIndex(index).getDataPtr();  // to be set later when startAdvertising() is called
00174                     
00175                     uint8_t Appearance[2];
00176                     uint16_t devP = (uint16_t)*deviceAppearance;
00177                     STORE_LE_16(Appearance, (uint16_t)devP);
00178     
00179                     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 */
00180                     
00181                     aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (tHalUint8 *)deviceAppearance);//not using array Appearance[2]
00182                     break;
00183                 case GapAdvertisingData::ADVERTISING_INTERVAL:               /**< Advertising Interval */
00184                     advtInterval = (uint16_t)(*loadPtr.getUnitAtIndex(index).getDataPtr());
00185                     DEBUG("advtInterval=%d\n\r", advtInterval);
00186                 break;
00187                 case GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA:        /**< Manufacturer Specific Data */                                
00188                 break;
00189                                 
00190             }          
00191     }
00192         //Set the SCAN_RSP Payload
00193         scan_response_payload = scanResponse.getPayload();
00194         scan_rsp_length = scanResponse.getPayloadLen();
00195     }
00196    return BLE_ERROR_NONE;
00197 }
00198 
00199 /**************************************************************************/
00200 /*!
00201     @brief  Starts the BLE HW, initialising any services that were
00202             added before this function was called.
00203 
00204     @note   All services must be added before calling this function!
00205 
00206     @returns    ble_error_t
00207 
00208     @retval     BLE_ERROR_NONE
00209                 Everything executed properly
00210 
00211     @section EXAMPLE
00212 
00213     @code
00214 
00215     @endcode
00216 */
00217 /**************************************************************************/
00218 ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams &params)
00219 {
00220     /* Make sure we support the advertising type */
00221     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
00222         /* ToDo: This requires a propery security implementation, etc. */
00223         return BLE_ERROR_NOT_IMPLEMENTED;
00224     }
00225 
00226     /* Check interval range */
00227     if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
00228         /* Min delay is slightly longer for unconnectable devices */
00229         if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
00230             (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) {
00231             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00232         }
00233     } else {
00234         if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN) ||
00235             (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) {
00236             return BLE_ERROR_PARAM_OUT_OF_RANGE;
00237         }
00238     }
00239 
00240     /* Check timeout is zero for Connectable Directed */
00241     if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
00242         /* Timeout must be 0 with this type, although we'll never get here */
00243         /* since this isn't implemented yet anyway */
00244         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00245     }
00246 
00247     /* Check timeout for other advertising types */
00248     if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
00249         (params.getTimeout() > GAP_ADV_PARAMS_TIMEOUT_MAX)) {
00250         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00251     }
00252 
00253   tBleStatus ret;
00254   
00255   //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};
00256   //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,device_name[27],device_name[28],device_name[29],device_name[30], device_name[31],
00257    //                                                     device_name[32], device_name[33], device_name[34], device_name[35], device_name[36]};
00258   
00259 
00260   
00261   //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,device_name[27],device_name[28]};
00262   const LongUUID_t HRM_SERVICE_UUID_128 = {0x18, 0x0D};
00263   /* set scan response data */
00264   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[]);*/
00265   
00266   /*aci_gap_set_discoverable(Advertising_Event_Type, Adv_min_intvl, Adv_Max_Intvl, Addr_Type, Adv_Filter_Policy,
00267                         Local_Name_Length, local_name, service_uuid_length, service_uuid_list, Slave_conn_intvl_min, Slave_conn_intvl_max);*/
00268   /*LINK_LAYER.H DESCRIBES THE ADVERTISING TYPES*/ 
00269 
00270   char* name = NULL;
00271   uint8_t nameLen = 0; 
00272   if(local_name!=NULL) {
00273       name = (char*)local_name;
00274       DEBUG("name=%s\n\r", name); 
00275       nameLen = local_name_length;
00276   } else {
00277       char str[] = "ST_BLE_DEV";
00278       name = new char[strlen(str)+1];
00279       name[0] = AD_TYPE_COMPLETE_LOCAL_NAME;
00280       strcpy(name+1, str);
00281       nameLen = strlen(name);
00282       DEBUG("nameLen=%d\n\r", nameLen);
00283       DEBUG("name=%s\n\r", name);      
00284   }  
00285   
00286                                
00287   advtInterval = params.getInterval(); // set advtInterval in case it is not already set by user application    
00288   ret = aci_gap_set_discoverable(params.getAdvertisingType(), // Advertising_Event_Type                                
00289                                 0,   // Adv_Interval_Min
00290                                 advtInterval,   // Adv_Interval_Max
00291                                 PUBLIC_ADDR, // Address_Type <hdd> It seems there is some problem with RANDOM_ADDRESS. <problem_desc> When RANDOM_ADDRESS is selected device name is not being handled properly, i.e. wrong device name is seen by android app </problem_desc>
00292                                 NO_WHITE_LIST_USE,  // Adv_Filter_Policy
00293                                 nameLen, //local_name_length, // Local_Name_Length
00294                                 (const char*)name, //local_name, // Local_Name
00295                                 servUuidlength,  //Service_Uuid_Length
00296                                 servUuidData, //Service_Uuid_List
00297                                 0, // Slave_Conn_Interval_Min
00298                                 0);  // Slave_Conn_Interval_Max
00299                        
00300   state.advertising = 1;
00301   
00302     return BLE_ERROR_NONE;
00303 }
00304 
00305 /**************************************************************************/
00306 /*!
00307     @brief  Stops the BLE HW and disconnects from any devices
00308 
00309     @returns    ble_error_t
00310 
00311     @retval     BLE_ERROR_NONE
00312                 Everything executed properly
00313 
00314     @section EXAMPLE
00315 
00316     @code
00317 
00318     @endcode
00319 */
00320 /**************************************************************************/
00321 ble_error_t BlueNRGGap::stopAdvertising(void)
00322 {
00323     tBleStatus ret;
00324     
00325     if(state.advertising == 1) {
00326     //Set non-discoverable to stop advertising
00327     ret = aci_gap_set_non_discoverable();
00328     
00329     if (ret != BLE_STATUS_SUCCESS){
00330       DEBUG("Error in stopping advertisement!!\n\r") ;
00331       return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value 
00332       //FIXME: Define Error values equivalent to BlueNRG Error Codes.
00333     }
00334     DEBUG("Advertisement stopped!!\n\r") ;
00335     //Set GapState_t::advertising state
00336     state.advertising = 0;
00337     }
00338     
00339     return BLE_ERROR_NONE;
00340 }
00341 
00342 /**************************************************************************/
00343 /*!
00344     @brief  Disconnects if we are connected to a central device
00345 
00346     @returns    ble_error_t
00347 
00348     @retval     BLE_ERROR_NONE
00349                 Everything executed properly
00350 
00351     @section EXAMPLE
00352 
00353     @code
00354 
00355     @endcode
00356 */
00357 /**************************************************************************/
00358 ble_error_t BlueNRGGap::disconnect(void)
00359 {
00360     tBleStatus ret;
00361     //For Reason codes check BlueTooth HCI Spec
00362     
00363     if(m_connectionHandle != BLE_CONN_HANDLE_INVALID) {
00364         ret = aci_gap_terminate(m_connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. 
00365 
00366     if (ret != BLE_STATUS_SUCCESS){
00367       DEBUG("Error in GAP termination!!\n\r") ;
00368       return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value 
00369       //FIXME: Define Error values equivalent to BlueNRG Error Codes.
00370     }
00371     
00372     //DEBUG("Disconnected from localhost!!\n\r") ;
00373     m_connectionHandle = BLE_CONN_HANDLE_INVALID;
00374     }
00375     
00376     return BLE_ERROR_NONE;
00377 }
00378 
00379 /**************************************************************************/
00380 /*!
00381     @brief  Sets the 16-bit connection handle
00382 */
00383 /**************************************************************************/
00384 void BlueNRGGap::setConnectionHandle(uint16_t con_handle)
00385 {
00386     m_connectionHandle = con_handle;
00387 }
00388 
00389 /**************************************************************************/
00390 /*!
00391     @brief  Gets the 16-bit connection handle
00392 */
00393 /**************************************************************************/
00394 uint16_t BlueNRGGap::getConnectionHandle(void)
00395 {
00396     return m_connectionHandle;
00397 }
00398 
00399 /**************************************************************************/
00400 /*!
00401     @brief      Sets the BLE device address. SetAddress will reset the BLE
00402                 device and re-initialize BTLE. Will not start advertising.
00403 
00404     @returns    ble_error_t
00405 
00406     @section EXAMPLE
00407 
00408     @code
00409 
00410     @endcode
00411 */
00412 /**************************************************************************/
00413 ble_error_t BlueNRGGap::setAddress(addr_type_t type, const uint8_t address[6])
00414 {
00415     tBleStatus ret;
00416     
00417     if (type > ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) {
00418         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00419     }
00420         
00421     //copy address to bdAddr[6]
00422     for(int i=0; i<BDADDR_SIZE; i++) {
00423         bdaddr[i] = address[i];
00424         //DEBUG("i[%d]:0x%x\n\r",i,bdaddr[i]);
00425         }
00426         
00427     if(!isSetAddress) isSetAddress = true;
00428     
00429     //Re-Init the BTLE Device with SetAddress as true
00430     //if(BlueNRGDevice::getIsInitialized())//Re-init only initialization is already done
00431         btle_init(isSetAddress);
00432     
00433     //if (ret==BLE_STATUS_SUCCESS)
00434     return BLE_ERROR_NONE;
00435 }
00436 
00437 /**************************************************************************/
00438 /*!
00439     @brief      Returns boolean if the address of the device has been set
00440                 or not
00441                 
00442     @returns    bool
00443 
00444     @section EXAMPLE
00445 
00446     @code
00447 
00448     @endcode
00449 */
00450 /**************************************************************************/
00451 bool BlueNRGGap::getIsSetAddress() 
00452 {
00453     return isSetAddress;   
00454 }
00455 
00456 /**************************************************************************/
00457 /*!
00458     @brief      Returns the address of the device if set
00459 
00460     @returns    ble_error_t
00461 
00462     @section EXAMPLE
00463 
00464     @code
00465 
00466     @endcode
00467 */
00468 /**************************************************************************/
00469 tHalUint8* BlueNRGGap::getAddress() 
00470 {
00471     if(isSetAddress)
00472     return bdaddr; 
00473     else return NULL;   
00474 }
00475 
00476 /**************************************************************************/
00477 /*!
00478     @brief      obtains preferred connection params
00479 
00480     @returns    ble_error_t
00481 
00482     @section EXAMPLE
00483 
00484     @code
00485 
00486     @endcode
00487 */
00488 /**************************************************************************/
00489 ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) 
00490 {
00491     return BLE_ERROR_NONE;
00492 }
00493 
00494 
00495 /**************************************************************************/
00496 /*!
00497     @brief      sets preferred connection params
00498 
00499     @returns    ble_error_t
00500 
00501     @section EXAMPLE
00502 
00503     @code
00504 
00505     @endcode
00506 */
00507 /**************************************************************************/
00508 ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) 
00509 {
00510     return BLE_ERROR_NONE;
00511 }
00512 
00513 /**************************************************************************/
00514 /*!
00515     @brief      updates preferred connection params
00516 
00517     @returns    ble_error_t
00518 
00519     @section EXAMPLE
00520 
00521     @code
00522 
00523     @endcode
00524 */
00525 /**************************************************************************/
00526 ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params)
00527 {
00528     return BLE_ERROR_NONE;
00529 }
00530