Fork of BlueNRG library to be compatible with bluetooth demo application

Dependents:   Nucleo_BLE_Demo Nucleo_BLE_Demo

Fork of Nucleo_BLE_BlueNRG by ST Americas mbed Team

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     uint8_t type;
00046     uint16_t short_uuid;
00047     uint8_t primary_short_uuid[2];
00048     uint8_t primary_base_uuid[16];
00049     uint8_t char_base_uuid[16];
00050     const uint8_t *base_uuid;
00051     const uint8_t *base_char_uuid;
00052     
00053     type = (service.getUUID()).shortOrLong();
00054     DEBUG("AddService(): Type:%d\n\r", type);
00055     
00056     /* Add the service to the BlueNRG */
00057     short_uuid = (service.getUUID()).getShortUUID();
00058     STORE_LE_16(primary_short_uuid, short_uuid);
00059     
00060     if(type==UUID::UUID_TYPE_LONG) {
00061         base_uuid = (service.getUUID()).getBaseUUID();   
00062         
00063         COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],base_uuid[13],base_uuid[12],base_uuid[11],base_uuid[10],base_uuid[9],
00064         base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],primary_short_uuid[1],primary_short_uuid[0],base_uuid[1],base_uuid[0]);
00065     }
00066     
00067     if(type==UUID::UUID_TYPE_SHORT) {
00068         ret = aci_gatt_add_serv(UUID_TYPE_16, primary_short_uuid, PRIMARY_SERVICE, 7, 
00069         &servHandle);
00070     }
00071     else if(type==UUID::UUID_TYPE_LONG) {
00072         ret = aci_gatt_add_serv(UUID_TYPE_128, primary_base_uuid, PRIMARY_SERVICE, 7, 
00073         &servHandle);
00074     }
00075     
00076     service.setHandle(servHandle);
00077     //serviceHandleVector.push_back(servHandle);
00078     DEBUG("added servHandle handle =%u\n\r", servHandle);
00079     tHalUint16 bleCharacteristic;
00080     
00081     //iterate to include all characteristics
00082     for (uint8_t i = 0; i < service.getCharacteristicCount(); i++) {
00083         GattCharacteristic *p_char = service.getCharacteristic(i);
00084         uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID();   
00085         
00086         uint8_t int_8_uuid[2];
00087         STORE_LE_16(int_8_uuid, char_uuid);
00088         
00089         if(type==UUID::UUID_TYPE_LONG) {
00090             base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID();
00091             
00092             COPY_UUID_128(char_base_uuid, base_char_uuid[15],base_char_uuid[14],base_char_uuid[13],base_char_uuid[12],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],
00093             base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],int_8_uuid[1],int_8_uuid[0],base_char_uuid[1],base_char_uuid[0]);
00094         }
00095         
00096         DEBUG("Char Properties 0x%x\n\r", p_char->getProperties());
00097         /*
00098         * Gatt_Evt_Mask -> HardCoded (0)
00099         * Encryption_Key_Size -> Hardcoded (16)
00100         * isVariable (variable length value field) -> Hardcoded (1)
00101         */
00102         tGattServerEvent Gatt_Evt_Mask = 0x0;
00103         
00104         if((p_char->getProperties() &
00105                     (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE|
00106                         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) {
00107             DEBUG("Setting up Gatt GATT_SERVER_ATTR_WRITE Mask\n\r");
00108             Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_SERVER_ATTR_WRITE;
00109         }
00110         if((p_char->getProperties() &
00111                     (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ|
00112                         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) {
00113             DEBUG("Setting up Gatt GATT_INTIMATE_APPL_WHEN_READ_N_WAIT Mask\n\r");
00114             Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_INTIMATE_APPL_WHEN_READ_N_WAIT; 
00115         }    //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check.
00116         
00117         if(type==UUID::UUID_TYPE_SHORT) {
00118             ret =  aci_gatt_add_char(service.getHandle(), UUID_TYPE_16, int_8_uuid, p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/,
00119             p_char->getProperties(), ATTR_PERMISSION_NONE, Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
00120             16 /*Encryption_Key_Size*/, 1 /*isVariable*/, &bleCharacteristic);
00121         }
00122         else if(type==UUID::UUID_TYPE_LONG) {
00123             ret =  aci_gatt_add_char(service.getHandle(), UUID_TYPE_128, char_base_uuid, p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/,
00124             p_char->getProperties(), ATTR_PERMISSION_NONE, Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
00125             16 /*Encryption_Key_Size*/, 1 /*isVariable*/, &bleCharacteristic);
00126         }
00127         /* Update the characteristic handle */
00128         uint16_t charHandle = characteristicCount;   
00129         
00130         bleCharHanldeMap.insert(std::pair<tHalUint16, tHalUint16>(bleCharacteristic, servHandle)); 
00131         
00132         p_characteristics[characteristicCount++] = p_char;
00133         p_char->getValueAttribute().setHandle(bleCharacteristic);    //Set the characteristic count as the corresponding char handle
00134         DEBUG("added bleCharacteristic handle =%u\n\r", bleCharacteristic);
00135         
00136         if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getInitialLength() > 0)) {
00137             updateValue(p_char->getValueAttribute().getHandle(), p_char->getValueAttribute().getValuePtr(), p_char->getValueAttribute().getInitialLength(), false /* localOnly */);
00138         }
00139         
00140         // add descriptors now
00141         uint16_t descHandle = 0;
00142         for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) {
00143             GattAttribute *descriptor = p_char->getDescriptor(descIndex);
00144             uint16_t shortUUID = descriptor->getUUID().getShortUUID();
00145             const tHalUint8 uuidArray[] = {(shortUUID>>8)&0xFF, (shortUUID&0xFF)};
00146             ret = aci_gatt_add_char_desc(service.getHandle(), p_char->getValueAttribute().getHandle(), 
00147             CHAR_DESC_TYPE_16_BIT, uuidArray, descriptor->getMaxLength(), descriptor->getInitialLength(), 
00148             descriptor->getValuePtr(), CHAR_DESC_SECURITY_PERMISSION, CHAR_DESC_ACCESS_PERMISSION, GATT_SERVER_ATTR_READ_WRITE,
00149             MIN_ENCRY_KEY_SIZE, CHAR_ATTRIBUTE_LEN_IS_FIXED, &descHandle);
00150             if(ret==(tBleStatus)0) {
00151                 DEBUG("Descriptor added successfully, descriptor handle=%d\n\r", descHandle);
00152                 descriptor->setHandle(descHandle);
00153             }
00154         }
00155     }    
00156     
00157     serviceCount++;
00158     
00159     //FIXME: There is no GattService pointer array in GattServer. 
00160     //        There should be one? (Only the user is aware of GattServices!) Report to forum.
00161     
00162     return BLE_ERROR_NONE;
00163 }
00164 
00165 /**************************************************************************/
00166 /*!
00167     @brief  Reads the value of a characteristic, based on the service
00168             and characteristic index fields
00169 
00170     @param[in]  charHandle
00171                 The handle of the GattCharacteristic to read from
00172     @param[in]  buffer
00173                 Buffer to hold the the characteristic's value
00174                 (raw byte array in LSB format)
00175     @param[in]  len
00176                 The number of bytes read into the buffer
00177 
00178     @returns    ble_error_t
00179 
00180     @retval     BLE_ERROR_NONE
00181                 Everything executed properly
00182 
00183     @section EXAMPLE
00184 
00185     @code
00186 
00187     @endcode
00188 */
00189 /**************************************************************************/
00190 ble_error_t BlueNRGGattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t *const lengthP)
00191 {
00192     DEBUG("ReadValue() Not Supported\n\r");
00193     return BLE_ERROR_NONE;
00194 }
00195 
00196 /**************************************************************************/
00197 /*!
00198     @brief  Updates the value of a characteristic, based on the service
00199             and characteristic index fields
00200 
00201     @param[in]  charHandle
00202                 The handle of the GattCharacteristic to write to
00203     @param[in]  buffer
00204                 Data to use when updating the characteristic's value
00205                 (raw byte array in LSB format)
00206     @param[in]  len
00207                 The number of bytes in buffer
00208 
00209     @returns    ble_error_t
00210 
00211     @retval     BLE_ERROR_NONE
00212                 Everything executed properly
00213 
00214     @section EXAMPLE
00215 
00216     @code
00217 
00218     @endcode
00219 */
00220 /**************************************************************************/
00221 ble_error_t BlueNRGGattServer::updateValue(uint16_t charHandle, uint8_t buffer[], uint16_t len, bool localOnly)
00222 {
00223     tBleStatus ret;    
00224     tHalUint8 buff[2];
00225 
00226     DEBUG("updating bleCharacteristic charHandle =%u, corresponding serviceHanle= %u\n\r", charHandle, bleCharHanldeMap.find(charHandle)->second);  
00227    
00228     ret = aci_gatt_update_char_value(bleCharHanldeMap.find(charHandle)->second, charHandle, 0, len, buffer);
00229 
00230     if (ret != BLE_STATUS_SUCCESS){
00231         DEBUG("Error while updating characteristic.\n\r") ;
00232         return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value 
00233         //FIXME: Define Error values equivalent to BlueNRG Error Codes.
00234     }
00235 
00236     //Generate Data Sent Event Here? (GattServerEvents::GATT_EVENT_DATA_SENT)  //FIXME: Is this correct?
00237     //Check if characteristic property is NOTIFY|INDICATE, if yes generate event
00238     GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(charHandle);
00239     if(p_char->getProperties() &  (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY
00240                 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) {
00241         BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_SENT, charHandle);
00242     }
00243 
00244     return BLE_ERROR_NONE;
00245 }
00246 
00247 /**************************************************************************/
00248 /*!
00249     @brief  Reads a value according to the handle provided
00250 
00251     @param[in]  charHandle
00252                 The handle of the GattCharacteristic to read from
00253 
00254     @returns    ble_error_t
00255 
00256     @retval     BLE_ERROR_NONE
00257                 Everything executed properly
00258 
00259     @section EXAMPLE
00260 
00261     @code
00262 
00263     @endcode
00264 */
00265 /**************************************************************************/
00266 ble_error_t BlueNRGGattServer::Read_Request_CB(tHalUint16 handle)
00267 {
00268     //signed short refvalue;
00269     uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle();
00270     
00271     //EXIT:
00272     if(gapConnectionHandle != 0)
00273     aci_gatt_allow_read(gapConnectionHandle);
00274 }
00275 
00276 /**************************************************************************/
00277 /*!
00278     @brief  Returns the GattCharacteristic according to the handle provided
00279 
00280     @param[in]  charHandle
00281                 The handle of the GattCharacteristic
00282 
00283     @returns    ble_error_t
00284 
00285     @retval     BLE_ERROR_NONE
00286                 Everything executed properly
00287 
00288     @section EXAMPLE
00289 
00290     @code
00291 
00292     @endcode
00293 */
00294 /**************************************************************************/
00295 GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(tHalUint16 attrHandle)
00296 {
00297     GattCharacteristic *p_char = NULL;
00298     int i;
00299     uint16_t handle;
00300 
00301     //DEBUG("BlueNRGGattServer::getCharacteristicFromHandle()>>Attribute Handle received 0x%x\n\r",attrHandle);
00302     for(i=0; i<characteristicCount; i++)
00303     {
00304         handle = p_characteristics[i]->getValueAttribute().getHandle();
00305         if(handle == attrHandle){
00306             p_char = p_characteristics[i];
00307             break;
00308         }
00309         /*if(i==characteristicCount-1)//Last Characteristic check
00310         {
00311             if(attrHandle>=bleCharacteristicHandles[handle])
00312             {
00313                 p_char = p_characteristics[i];
00314                 DEBUG("Found Characteristic Properties 0x%x\n\r",p_char->getProperties());
00315                 break;
00316             }            
00317         }
00318         else {
00319             //Testing if attribute handle is between two Characteristic Handles
00320             if(attrHandle>=bleCharacteristicHandles[handle] && attrHandle<bleCharacteristicHandles[handle+1])
00321             {
00322                 p_char = p_characteristics[i];
00323                 //DEBUG("Found Characteristic Properties 0x%x\n\r",p_char->getProperties());
00324                 break;
00325             } else continue;
00326         }*/
00327     }
00328 
00329     return p_char;
00330 }
00331 
00332