Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: HC_SR04_Ultrasonic_Library Servo mbed
Fork of FIP_REV1 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 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
Generated on Tue Jul 12 2022 21:41:59 by
