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 BlueNRGGattServer.cpp Source File

BlueNRGGattServer.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 "BlueNRGGattServer.h"
00018 #include "mbed.h"
00019 #include "BlueNRGGap.h"
00020 #include "Utils.h"
00021                           
00022 /**************************************************************************/
00023 /*!
00024     @brief  Adds a new service to the GATT table on the peripheral
00025 
00026     @returns    ble_error_t
00027 
00028     @retval     BLE_ERROR_NONE
00029                 Everything executed properly
00030 
00031     @section EXAMPLE
00032 
00033     @code
00034 
00035     @endcode
00036 */
00037 /**************************************************************************/
00038 ble_error_t BlueNRGGattServer::addService(GattService &service)
00039 {
00040     /* ToDo: Make sure we don't overflow the array, etc. */
00041     /* ToDo: Make sure this service UUID doesn't already exist (?) */
00042     /* ToDo: Basic validation */
00043     
00044     tBleStatus ret;
00045     
00046     DEBUG("AddService()\n\r");
00047     /* Add the service to the BlueNRG */
00048     uint16_t short_uuid = (service.getUUID()).getShortUUID();
00049     
00050     uint8_t primary_uuid[2];//= {0x0D,0x18};    
00051     STORE_LE_16(primary_uuid, short_uuid);
00052     
00053     //TODO: Check UUID existence??
00054     
00055     ret = aci_gatt_add_serv(UUID_TYPE_16, primary_uuid, PRIMARY_SERVICE, 7, 
00056                             &hrmServHandle);
00057     service.setHandle(hrmServHandle);
00058     
00059     //TODO: iterate to include all characteristics
00060     for (uint8_t i = 0; i < service.getCharacteristicCount(); i++) {
00061     GattCharacteristic *p_char = service.getCharacteristic(i);
00062     uint16_t char_uuid = (p_char->getUUID()).getShortUUID();
00063     
00064     uint8_t int_8_uuid[2];
00065     STORE_LE_16(int_8_uuid, char_uuid);
00066     //TODO: Check UUID existence??
00067     DEBUG("Char Properties 0x%x\n\r", p_char->getProperties());
00068     /*
00069     * Gatt_Evt_Mask -> HardCoded (0)
00070     * Encryption_Key_Size -> Hardcoded (16)
00071     * isVariable (variable length value field) -> Hardcoded (1)
00072     */
00073     tGattServerEvent Gatt_Evt_Mask = 0x0;
00074     
00075     if((p_char->getProperties() &
00076          (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE|
00077           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) {
00078             DEBUG("Setting up Gatt GATT_SERVER_ATTR_WRITE Mask\n\r");
00079             Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_SERVER_ATTR_WRITE;
00080         }
00081     if((p_char->getProperties() &
00082          (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ|
00083           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) {
00084             DEBUG("Setting up Gatt GATT_INTIMATE_APPL_WHEN_READ_N_WAIT Mask\n\r");
00085             Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_INTIMATE_APPL_WHEN_READ_N_WAIT; 
00086         }    //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check.
00087         
00088     ret =  aci_gatt_add_char(service.getHandle(), UUID_TYPE_16, int_8_uuid, p_char->getMaxLength() /*2*/ /*Value Length*/,
00089                            p_char->getProperties(), ATTR_PERMISSION_NONE, Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
00090                            16 /*Encryption_Key_Size*/, 1 /*isVariable*/, &bleCharacteristicHandles[characteristicCount]);
00091     
00092     /* Update the characteristic handle */
00093     uint16_t charHandle = characteristicCount;    
00094     
00095     p_characteristics[characteristicCount++] = p_char;
00096     p_char->setHandle(charHandle);    //Set the characteristic count as the corresponding char handle
00097     
00098     if ((p_char->getValuePtr() != NULL) && (p_char->getInitialLength() > 0)) {
00099             updateValue(charHandle, p_char->getValuePtr(), p_char->getInitialLength(), false /* localOnly */);
00100         }
00101     }    
00102                        
00103     serviceCount++;
00104     
00105     //FIXME: There is no GattService pointer array in GattServer. 
00106     //        There should be one? (Only the user is aware of GattServices!) Report to forum.
00107                     
00108     return BLE_ERROR_NONE;
00109 }
00110 
00111 
00112 /**************************************************************************/
00113 /*!
00114     @brief  Reads the value of a characteristic, based on the service
00115             and characteristic index fields
00116 
00117     @param[in]  charHandle
00118                 The handle of the GattCharacteristic to read from
00119     @param[in]  buffer
00120                 Buffer to hold the the characteristic's value
00121                 (raw byte array in LSB format)
00122     @param[in]  len
00123                 The number of bytes read into the buffer
00124 
00125     @returns    ble_error_t
00126 
00127     @retval     BLE_ERROR_NONE
00128                 Everything executed properly
00129 
00130     @section EXAMPLE
00131 
00132     @code
00133 
00134     @endcode
00135 */
00136 /**************************************************************************/
00137 ble_error_t BlueNRGGattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t *const lengthP)
00138 {
00139     DEBUG("ReadValue() Not Supported\n\r");
00140     return BLE_ERROR_NONE;
00141 }
00142 
00143 /**************************************************************************/
00144 /*!
00145     @brief  Updates the value of a characteristic, based on the service
00146             and characteristic index fields
00147 
00148     @param[in]  charHandle
00149                 The handle of the GattCharacteristic to write to
00150     @param[in]  buffer
00151                 Data to use when updating the characteristic's value
00152                 (raw byte array in LSB format)
00153     @param[in]  len
00154                 The number of bytes in buffer
00155 
00156     @returns    ble_error_t
00157 
00158     @retval     BLE_ERROR_NONE
00159                 Everything executed properly
00160 
00161     @section EXAMPLE
00162 
00163     @code
00164 
00165     @endcode
00166 */
00167 /**************************************************************************/
00168 ble_error_t BlueNRGGattServer::updateValue(uint16_t charHandle, uint8_t buffer[], uint16_t len, bool localOnly)
00169 {
00170   tBleStatus ret;    
00171   tHalUint8 buff[2];
00172     
00173   //STORE_LE_16(buff,125);
00174   
00175   //DEBUG("CharHandle: %d\n\r", charHandle);
00176   //DEBUG("Actual Handle: 0x%x\n\r", bleCharacteristicHandles[charHandle]);
00177   //DEBUG("Service Handle: 0x%x\n\r", hrmServHandle);
00178   //DEBUG("buffer[0]: %d\n\r", buffer[0]);
00179   //DEBUG("buffer[1]: %d\n\r", buffer[1]);
00180   //DEBUG("len: %d\n\r", len);
00181     
00182   ret = aci_gatt_update_char_value(hrmServHandle, bleCharacteristicHandles[charHandle], 0, len, buffer);
00183 
00184   if (ret != BLE_STATUS_SUCCESS){
00185       DEBUG("Error while updating characteristic.\n\r") ;
00186       return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value 
00187       //FIXME: Define Error values equivalent to BlueNRG Error Codes.
00188     }
00189 
00190   //Generate Data Sent Event Here? (GattServerEvents::GATT_EVENT_DATA_SENT)  //FIXME: Is this correct?
00191   //Check if characteristic property is NOTIFY|INDICATE, if yes generate event
00192   GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(bleCharacteristicHandles[charHandle]);
00193   if(p_char->getProperties() &  (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY
00194                                   | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) {
00195           BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_SENT);
00196       }
00197   
00198   return BLE_ERROR_NONE;
00199 }
00200 
00201 /**************************************************************************/
00202 /*!
00203     @brief  Reads a value according to the handle provided
00204 
00205     @param[in]  charHandle
00206                 The handle of the GattCharacteristic to read from
00207 
00208     @returns    ble_error_t
00209 
00210     @retval     BLE_ERROR_NONE
00211                 Everything executed properly
00212 
00213     @section EXAMPLE
00214 
00215     @code
00216 
00217     @endcode
00218 */
00219 /**************************************************************************/
00220 ble_error_t BlueNRGGattServer::Read_Request_CB(tHalUint16 handle)
00221 {
00222     //signed short refvalue;
00223     uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle();
00224     
00225     tBleStatus ret;
00226     uint16_t data;
00227     tHalUint8 buff[2];
00228         
00229     data = 450 + ((uint64_t)rand()*100)/RAND_MAX;
00230     STORE_LE_16(buff,data);
00231     
00232     //ret = aci_gatt_update_char_value(hrmServHandle, handle, 0, sizeof(buff), buff);
00233     //ret = aci_gatt_read_charac_val(gapConnectionHandle, handle);
00234     
00235     //EXIT:
00236     if(gapConnectionHandle != 0)
00237     aci_gatt_allow_read(gapConnectionHandle);
00238 }
00239 
00240 /**************************************************************************/
00241 /*!
00242     @brief  Returns the GattCharacteristic according to the handle provided
00243 
00244     @param[in]  charHandle
00245                 The handle of the GattCharacteristic
00246 
00247     @returns    ble_error_t
00248 
00249     @retval     BLE_ERROR_NONE
00250                 Everything executed properly
00251 
00252     @section EXAMPLE
00253 
00254     @code
00255 
00256     @endcode
00257 */
00258 /**************************************************************************/
00259 GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(tHalUint16 attrHandle)
00260 {
00261     GattCharacteristic *p_char;
00262     int i;
00263     uint16_t handle;
00264     
00265     //DEBUG("BlueNRGGattServer::getCharacteristicFromHandle()>>Attribute Handle received 0x%x\n\r",attrHandle);
00266     for(i=0; i<characteristicCount; i++)
00267     {
00268         handle = p_characteristics[i]->getHandle();
00269         
00270         if(i==characteristicCount-1)//Last Characteristic check
00271         {
00272             if(attrHandle>=bleCharacteristicHandles[handle])
00273             {
00274                 p_char = p_characteristics[i];
00275                 //DEBUG("Found Characteristic Properties 0x%x\n\r",p_char->getProperties());
00276                 break;
00277                 }            
00278         }
00279         else {
00280             //Testing if attribute handle is between two Characteristic Handles
00281             if(attrHandle>=bleCharacteristicHandles[handle] && attrHandle<bleCharacteristicHandles[handle+1])
00282             {
00283                 p_char = p_characteristics[i];
00284                 //DEBUG("Found Characteristic Properties 0x%x\n\r",p_char->getProperties());
00285                 break;
00286             } else continue;
00287         }
00288     }
00289     return p_char;
00290 }
00291 
00292 /**************************************************************************/
00293 /*!
00294     @brief  sets device name characteristic 
00295 
00296     @param[in]  deviceName
00297                 pointer to device name to be set
00298 
00299     @returns    ble_error_t
00300 
00301     @retval     BLE_ERROR_NONE
00302                 Everything executed properly
00303 
00304     @section EXAMPLE
00305 
00306     @code
00307 
00308     @endcode
00309 */
00310 /**************************************************************************/
00311 ble_error_t BlueNRGGattServer::setDeviceName(const uint8_t *deviceName) 
00312 {
00313     int ret;
00314     uint8_t nameLen = 0;     
00315     
00316     DeviceName = (uint8_t *)deviceName;
00317     //DEBUG("SetDeviceName=%s\n\r", DeviceName);
00318     
00319     nameLen = strlen((const char*)DeviceName);
00320     //DEBUG("DeviceName Size=%d\n\r", nameLen); 
00321     
00322     ret = aci_gatt_update_char_value(g_gap_service_handle, 
00323                                                 g_device_name_char_handle, 
00324                                                 0, 
00325                                                 nameLen, 
00326                                                 (tHalUint8 *)DeviceName);
00327                                                 
00328     if(ret){
00329         DEBUG("device set name failed\n\r");            
00330         return BLE_ERROR_PARAM_OUT_OF_RANGE;//TODO:Wrong error code
00331     }
00332   
00333     return BLE_ERROR_NONE;
00334 }
00335 
00336 /**************************************************************************/
00337 /*!
00338     @brief  gets device name characteristic 
00339 
00340     @param[in]  deviceName
00341                 pointer to device name 
00342                 
00343 
00344     @param[in]  lengthP
00345                 pointer to device name length                
00346 
00347     @returns    ble_error_t
00348 
00349     @retval     BLE_ERROR_NONE
00350                 Everything executed properly
00351 
00352     @section EXAMPLE
00353 
00354     @code
00355 
00356     @endcode
00357 */
00358 /**************************************************************************/
00359 ble_error_t BlueNRGGattServer::getDeviceName(uint8_t *deviceName, unsigned *lengthP) 
00360 {   
00361     int ret;
00362     
00363     if(DeviceName==NULL) 
00364         return BLE_ERROR_PARAM_OUT_OF_RANGE;
00365     
00366     strcpy((char*)deviceName, (const char*)DeviceName);
00367     //DEBUG("GetDeviceName=%s\n\r", deviceName);
00368     
00369     *lengthP = strlen((const char*)DeviceName);
00370     //DEBUG("DeviceName Size=%d\n\r", *lengthP); 
00371     
00372     return BLE_ERROR_NONE;
00373 }
00374 
00375 /**************************************************************************/
00376 /*!
00377     @brief  sets device appearance characteristic 
00378 
00379     @param[in]  appearance
00380                 device appearance      
00381 
00382     @returns    ble_error_t
00383 
00384     @retval     BLE_ERROR_NONE
00385                 Everything executed properly
00386 
00387     @section EXAMPLE
00388 
00389     @code
00390 
00391     @endcode
00392 */
00393 /**************************************************************************/
00394 ble_error_t BlueNRGGattServer::setAppearance(uint16_t appearance)
00395 {
00396     /* 
00397     Tested with GapAdvertisingData::GENERIC_PHONE. 
00398     for other appearances BLE Scanner android app is not behaving properly 
00399     */
00400     //char deviceAppearance[2];   
00401     STORE_LE_16(deviceAppearance, appearance);                 
00402     DEBUG("input: incoming = %d deviceAppearance= 0x%x 0x%x\n\r", appearance, deviceAppearance[1], deviceAppearance[0]);
00403     
00404     aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (tHalUint8 *)deviceAppearance);
00405     
00406     return BLE_ERROR_NONE;    
00407 }
00408 
00409 /**************************************************************************/
00410 /*!
00411     @brief  gets device appearance  
00412 
00413     @param[in]  appearance
00414                 pointer to device appearance value      
00415 
00416     @returns    ble_error_t
00417 
00418     @retval     BLE_ERROR_NONE
00419                 Everything executed properly
00420 
00421     @section EXAMPLE
00422 
00423     @code
00424 
00425     @endcode
00426 */
00427 /**************************************************************************/
00428 ble_error_t BlueNRGGattServer::getAppearance(uint16_t *appearanceP)
00429 {
00430     uint16_t devP;
00431     if(!appearanceP) return BLE_ERROR_PARAM_OUT_OF_RANGE;
00432     devP = ((uint16_t)(0x0000|deviceAppearance[0])) | (((uint16_t)(0x0000|deviceAppearance[1]))<<8);
00433     strcpy((char*)appearanceP, (const char*)&devP);
00434     
00435     return BLE_ERROR_NONE;    
00436 }
00437