Fork of BlueNRG library to be compatible with bluetooth demo application
Dependents: Nucleo_BLE_Demo Nucleo_BLE_Demo
Fork of Nucleo_BLE_BlueNRG by
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
Generated on Sat Jul 16 2022 01:53:16 by 1.7.2