Lorenzo Invidia / target_st_bluenrg

Dependents:   ble-star-mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BlueNRGGattConnectionClient.cpp Source File

BlueNRGGattConnectionClient.cpp

Go to the documentation of this file.
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   ******************************************************************************
00018   * @file    BlueNRGGattServer.cpp
00019   * @author  STMicroelectronics
00020   * @brief   Implementation of BlueNRG BLE_API GattServer Class
00021   ******************************************************************************
00022   * @copy
00023   *
00024   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00025   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
00026   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
00027   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00028   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00029   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00030   *
00031   * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
00032   */
00033 
00034 /** @defgroup BlueNRGGattConnectionClient
00035  *  @brief BlueNRG GattConnectionClient Adaptation
00036  *  @{
00037  */
00038 
00039 #include "BlueNRGGattConnectionClient.h"
00040 #ifdef YOTTA_CFG_MBED_OS
00041     #include "mbed-drivers/mbed.h"
00042 #else
00043     #include "mbed.h"
00044 #endif 
00045 #include "BlueNRGGap.h" 
00046 #include "BlueNRGGattClient.h"
00047 #include "ble_utils.h"
00048 #include "ble_debug.h"
00049 
00050 // #define PRINTF printf
00051 
00052 static uint8_t props_mask[] = {
00053   0x01,
00054   0x02,
00055   0x04,
00056   0x08,
00057   0x10,
00058   0x20,
00059   0x40,
00060   0x80
00061   };
00062 
00063 void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code)
00064 {
00065   if(error_code != BLE_STATUS_SUCCESS) {
00066     _currentState = GATT_IDLE;
00067     return;
00068   }
00069 
00070   // Service Discovery complete
00071 /*
00072   if(_currentState != GATT_IDLE &&
00073      _currentState != GATT_DISCOVERY_TERMINATED &&
00074      _currentState != GATT_WRITE_CHAR &&
00075      _currentState != GATT_READ_CHAR) {
00076 */
00077   if(_currentState == GATT_SERVICE_DISCOVERY) {
00078     findServiceChars();
00079     return;
00080   }
00081 
00082   if(_currentState == GATT_CHAR_DESC_DISCOVERY) {
00083       _currentState = GATT_IDLE;
00084       if(charDescTerminationCallback != NULL) {
00085          CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = {
00086                                    _characteristic,
00087                                    BLE_ERROR_NONE
00088          };
00089          charDescTerminationCallback(&params);
00090        }
00091       return;
00092   }
00093 
00094   // Read complete
00095   if(_currentState == GATT_READ_CHAR) {
00096     _currentState = GATT_IDLE;
00097     BlueNRGGattClient::getInstance().processReadResponse(&readCBParams);
00098     free((void*)(readCBParams.data));
00099     readCBParams.data = NULL;
00100     return;
00101   }
00102 
00103   // Write complete
00104   if(_currentState == GATT_WRITE_CHAR) {
00105     _currentState = GATT_IDLE;
00106     BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
00107     return;
00108   }
00109 }
00110 
00111 void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length,
00112                                                     uint8_t attribute_data_length,
00113                                                     uint8_t *attribute_data_list)
00114 {
00115   GattAttribute::Handle_t startHandle, endHandle;
00116   UUID uuid;
00117   uint8_t i, offset, numAttr;
00118 
00119   numAttr = (event_data_length - 1) / attribute_data_length;
00120 
00121   offset = 0;
00122   for (i=0; i<numAttr; i++) {
00123     startHandle = attribute_data_list[offset];
00124     endHandle = attribute_data_list[offset+2];
00125 
00126     // UUID Type
00127     if (attribute_data_length == 6) {
00128 
00129       PRINTF("UUID_TYPE_16\n\r");
00130       uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4];
00131       PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle);
00132 
00133     } else {
00134 
00135       PRINTF("UUID_TYPE_128\n\r");
00136       uuid.setupLong(attribute_data_list+offset+4, UUID::LSB);
00137 
00138 #ifdef DEBUG
00139       PRINTF("S UUID-");
00140       const uint8_t *longUUIDBytes = uuid.getBaseUUID();
00141       for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) {
00142         PRINTF("%02x", longUUIDBytes[j]);
00143       }
00144 #endif
00145       PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle);
00146 
00147     }
00148 
00149     PRINTF("Setup serviceIndex = %d\n\r", _numServices);
00150     discoveredService[_numServices].setup(uuid, startHandle, endHandle);
00151 
00152     _numServices++;
00153 
00154     offset += attribute_data_length;
00155   }
00156 
00157   PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr);
00158 
00159 }
00160 
00161 void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list)
00162 {
00163   GattAttribute::Handle_t startHandle, endHandle;
00164   UUID uuid;
00165   uint8_t i, offset, numHandlePairs;
00166 
00167   numHandlePairs = (event_data_length - 1) / 2;
00168 
00169   offset = 0;
00170   for (i=0; i<numHandlePairs; i++) {
00171     startHandle = handles_info_list[offset];
00172     endHandle = handles_info_list[offset+2];
00173 
00174     PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle);
00175 
00176 
00177     if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) {
00178         PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle);
00179         uuid = _matchingServiceUUID.getShortUUID();
00180     } else {
00181 #ifdef DEBUG
00182         PRINTF("S UUID-");
00183         const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID();
00184         for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
00185             PRINTF("%02x", longUUIDBytes[i]);
00186         }
00187 #endif
00188         PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle);
00189         uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB);
00190     }
00191 
00192     discoveredService[i].setup(uuid, startHandle, endHandle);
00193 
00194     _numServices++;
00195 
00196     offset += 4;
00197   }
00198 }
00199 
00200 void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length,
00201                                                  uint8_t handle_value_pair_length,
00202                                                  uint8_t *handle_value_pair)
00203 {
00204   // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
00205 
00206   GattAttribute::Handle_t declHandle, valueHandle, lastHandle;
00207   UUID uuid;
00208   uint8_t i, numChar, offset;
00209 
00210   numChar = (event_data_length - 1) / handle_value_pair_length;
00211 
00212   PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar);
00213 
00214   offset = 0;
00215   for (i=0; i<numChar; i++) {
00216     // UUID Type
00217     if (handle_value_pair_length == 7) {
00218       PRINTF("Char UUID_TYPE_16\n\r");
00219       uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5];
00220       PRINTF("C UUID-%X\r\n", uuid.getShortUUID());
00221     } else {
00222       PRINTF("Char UUID_TYPE_128\n\r");
00223       uuid.setupLong(handle_value_pair+offset+5, UUID::LSB);
00224 #ifdef DEBUG
00225       PRINTF("C UUID-");
00226       const uint8_t *longUUIDBytes = uuid.getBaseUUID();
00227       for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
00228         PRINTF("%02X", longUUIDBytes[i]);
00229       }
00230       PRINTF("\r\n");
00231 #endif
00232     }
00233 
00234     // Properties
00235     DiscoveredCharacteristic::Properties_t p;
00236 
00237     p._broadcast = (props_mask[0] & handle_value_pair[offset+2]);
00238     p._read = (props_mask[1] & handle_value_pair[offset+2])>>1;
00239     p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2;
00240     p._write = (props_mask[3] & handle_value_pair[offset+2])>>3;
00241     p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4;
00242     p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5;
00243     p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6;
00244     PRINTF("p._broadcast=%d\n\r", p._broadcast);
00245     PRINTF("p._read=%d\n\r", p._read);
00246     PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp);
00247     PRINTF("p._write=%d\n\r", p._write);
00248     PRINTF("p._notify=%d\n\r", p._notify);
00249     PRINTF("p._indicate=%d\n\r", p._indicate);
00250     PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite);
00251 
00252     /*
00253     uint8_t props = handle_value_pair[offset+2];
00254     PRINTF("CHAR PROPS: %d\n\r", props);
00255     */
00256 
00257     // Handles
00258     declHandle = handle_value_pair[offset];
00259     valueHandle = handle_value_pair[offset+3];
00260     lastHandle = valueHandle+1;
00261     PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle);
00262 
00263     discoveredChar[_numChars].setup(_gattClient,
00264                                     _connectionHandle,
00265                                     uuid,
00266                                     p,
00267                                     declHandle,
00268                                     valueHandle,
00269                                     lastHandle);
00270 
00271     if (_numChars != 0) {
00272         discoveredChar[_numChars - 1].setLastHandle(declHandle - 1);
00273 
00274         if(characteristicDiscoveryCallback) {
00275           characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]);
00276         }
00277     }
00278 
00279     _numChars++;
00280 
00281     offset += handle_value_pair_length;
00282   }
00283 }
00284 
00285 void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length,
00286                                                       uint16_t attr_handle,
00287                                                       uint8_t *attr_value)
00288 {
00289   // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
00290   GattAttribute::Handle_t declHandle, valueHandle, lastHandle;
00291   UUID uuid;
00292 
00293   PRINTF("serviceCharByUUIDCB\n\r");
00294 
00295   // UUID Type
00296   if (event_data_length == 7) {
00297     PRINTF("Char UUID_TYPE_16\n\r");
00298     uuid = attr_value[4]<<8|attr_value[3];
00299     PRINTF("C UUID-%X\r\n", uuid.getShortUUID());
00300   } else {
00301     PRINTF("Char UUID_TYPE_128\n\r");
00302     uuid.setupLong(attr_value+3, UUID::LSB);
00303 #ifdef DEBUG
00304     PRINTF("C UUID-");
00305     const uint8_t *longUUIDBytes = uuid.getBaseUUID();
00306     for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
00307       PRINTF("%02X", longUUIDBytes[i]);
00308     }
00309     PRINTF("\r\n");
00310 #endif
00311   }
00312 
00313   // Properties
00314   DiscoveredCharacteristic::Properties_t p;
00315 
00316   p._broadcast = (props_mask[0] & attr_value[0]);
00317   p._read = (props_mask[1] & attr_value[0])>>1;
00318   p._writeWoResp = (props_mask[2] & attr_value[0])>>2;
00319   p._write = (props_mask[3] & attr_value[0])>>3;
00320   p._notify = (props_mask[4] & attr_value[0])>>4;
00321   p._indicate = (props_mask[5] & attr_value[0])>>5;
00322   p._authSignedWrite = (props_mask[6] & attr_value[0])>>6;
00323   PRINTF("p._broadcast=%d\n\r", p._broadcast);
00324   PRINTF("p._read=%d\n\r", p._read);
00325   PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp);
00326   PRINTF("p._write=%d\n\r", p._write);
00327   PRINTF("p._notify=%d\n\r", p._notify);
00328   PRINTF("p._indicate=%d\n\r", p._indicate);
00329   PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite);
00330 
00331   /*
00332   uint8_t props = attr_value[0];
00333   PRINTF("CHAR PROPS: %d\n\r", props);
00334   */
00335 
00336   // Handles
00337   declHandle = attr_handle;
00338   valueHandle = attr_value[1];
00339   lastHandle = valueHandle+1;
00340 
00341   discoveredChar[_numChars].setup(_gattClient,
00342                                   _connectionHandle,
00343                                   uuid,
00344                                   p,
00345                                   declHandle,
00346                                   valueHandle,
00347                                   lastHandle);
00348 
00349   // update the last handle and call the characteristic discovery callback for previous char
00350   if (_numChars != 0) {
00351     discoveredChar[_numChars - 1].setLastHandle(declHandle - 1);
00352 
00353     if(characteristicDiscoveryCallback) {
00354       characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]);
00355     }
00356   }
00357 
00358   _numChars++;
00359 }
00360 
00361 ble_error_t BlueNRGGattConnectionClient::findServiceChars(void)
00362 {
00363   PRINTF("findServiceChars\n\r");
00364 
00365   tBleStatus ret;
00366   uint8_t uuid_type = UUID_TYPE_16;
00367   uint8_t short_uuid[2];
00368   uint8_t *uuid = NULL;
00369 
00370   DiscoveredService *service;
00371 
00372   // complete the discovery of the last characteristic of the previous service.
00373   // Its last handle wasn't known before this point
00374   // update the handle and call the characteristic discovery callback.
00375   if (_servIndex != 0 && _numChars != 0) {
00376       discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle());
00377 
00378       if(characteristicDiscoveryCallback) {
00379         characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]);
00380       }
00381   }
00382 
00383   _numChars = 0;
00384 
00385   // We finished chars discovery for all services
00386   if(_servIndex >= _numServices) {
00387     PRINTF("!!!We finished chars discovery for all services!!!\n\r");
00388     //_currentState = GATT_CHARS_DISCOVERY_COMPLETE;
00389 
00390     terminateServiceDiscovery();
00391 
00392     return BLE_ERROR_NONE;
00393   }
00394 
00395   service = &discoveredService[_servIndex];
00396   /*
00397   if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
00398     PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID());
00399   } else {
00400     PRINTF("S UUID-");
00401     const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
00402     for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
00403       PRINTF("%02X", longUUIDBytes[i]);
00404     }
00405     PRINTF("\r\n");
00406   }
00407   */
00408 
00409   if(serviceDiscoveryCallback) {
00410     serviceDiscoveryCallback(service);
00411   }
00412 
00413   PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex);
00414   //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
00415 
00416     if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) {
00417         PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r");
00418         ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle());
00419     } else {
00420 
00421         uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong();
00422 
00423         if(type == UUID::UUID_TYPE_SHORT) {
00424             STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID());
00425 
00426             uuid_type = UUID_TYPE_16;
00427             uuid = short_uuid;
00428 #ifdef DEBUG
00429             PRINTF("findServiceChars C UUID-");
00430             for(unsigned i = 0; i < 2; i++) {
00431                 PRINTF("%02X", short_uuid[i]);
00432             }
00433             PRINTF("\n\r");
00434 #endif
00435         } else if(type==UUID::UUID_TYPE_LONG) {
00436 
00437             uuid_type = UUID_TYPE_128;
00438             uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID();
00439 #ifdef DEBUG
00440             PRINTF("(findServiceChars) C UUID-");
00441             for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
00442                 PRINTF("%02X", uuid[i]);
00443             }
00444             PRINTF("\r\n");
00445 #endif
00446         }
00447 
00448         ret = aci_gatt_disc_charac_by_uuid(_connectionHandle,
00449                                            service->getStartHandle(),
00450                                            service->getEndHandle(),
00451                                            uuid_type,
00452                                            uuid);
00453     }
00454 
00455   if(ret == BLE_STATUS_SUCCESS) {
00456     _servIndex++;
00457   }
00458 
00459   PRINTF("findServiceChars ret=%d\n\r", ret);
00460 
00461   return BLE_ERROR_NONE;
00462 }
00463 
00464 ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t         sc,
00465                                                                 ServiceDiscovery::CharacteristicCallback_t  cc,
00466                                                                 const UUID                                 &matchingServiceUUID,
00467                                                                 const UUID                                 &matchingCharacteristicUUIDIn)
00468 {
00469   PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r");
00470 
00471   tBleStatus ret;
00472   uint8_t uuid_type = UUID_TYPE_16;
00473   uint8_t short_uuid[2];
00474   uint8_t *uuid = NULL;
00475   unsigned j;
00476 
00477   if(isServiceDiscoveryActive()) {
00478     return BLE_ERROR_OPERATION_NOT_PERMITTED;
00479   }
00480 
00481   if(!sc && !cc) {
00482     // nothing to do
00483     PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r");
00484     return BLE_ERROR_NONE;
00485   }
00486 
00487   serviceDiscoveryCallback = sc;
00488   characteristicDiscoveryCallback = cc;
00489   _matchingServiceUUID = matchingServiceUUID;
00490   _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn;
00491 
00492   //reset services
00493   _numServices = 0;
00494   _numChars = 0;
00495   _servIndex = 0;
00496   for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) {
00497     discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE);
00498   }
00499 
00500   if(matchingServiceUUID == BLE_UUID_UNKNOWN) {
00501 
00502     // Wildcard: search for all services
00503     PRINTF("Wildcard: search for all services\r\n");
00504     ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle);
00505 
00506   } else {
00507     PRINTF("search for specific services\r\n");
00508 
00509     uint8_t type = matchingServiceUUID.shortOrLong();
00510 
00511     if(type == UUID::UUID_TYPE_SHORT) {
00512       STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID());
00513 #ifdef DEBUG
00514       PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x");
00515       for(j = 0; j < 2; j++) {
00516         PRINTF("%02X", short_uuid[j]);
00517       }
00518       PRINTF("\n\r");
00519 #endif
00520 
00521       uuid_type = UUID_TYPE_16;
00522       uuid = short_uuid;
00523 
00524     } else if(type==UUID::UUID_TYPE_LONG) {
00525 
00526       uuid_type = UUID_TYPE_128;
00527       uuid = (unsigned char*)matchingServiceUUID.getBaseUUID();
00528 
00529 #ifdef DEBUG
00530       PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x");
00531       for(j = 0; j < 16; j++) {
00532         PRINTF("%02X", uuid[j]);
00533       }
00534       PRINTF("\n\r");
00535 #endif
00536     }
00537 
00538     // search for specific service by UUID
00539     ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid);
00540   }
00541 
00542   if(ret == BLE_STATUS_SUCCESS) {
00543     _currentState = GATT_SERVICE_DISCOVERY;
00544   }
00545 
00546   PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret);
00547 
00548   return BLE_ERROR_NONE;
00549 }
00550 
00551 ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t  callback,
00552                                                           const UUID                          &matchingServiceUUID)
00553 {
00554   /* avoid compiler warnings about unused variables */
00555   (void)callback;
00556   (void)matchingServiceUUID;
00557 
00558   return BLE_ERROR_NOT_IMPLEMENTED;
00559 }
00560 
00561 ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t  callback,
00562                                                           GattAttribute::Handle_t              startHandle,
00563                                                           GattAttribute::Handle_t              endHandle)
00564 {
00565   /* avoid compiler warnings about unused variables */
00566   (void)callback;
00567   (void)startHandle;
00568   (void)endHandle;
00569 
00570   return BLE_ERROR_NOT_IMPLEMENTED;
00571 }
00572 
00573 bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const
00574 {
00575   if(_currentState == GATT_SERVICE_DISCOVERY) {
00576     return true;
00577   }
00578 
00579   return false;
00580 }
00581 
00582 void BlueNRGGattConnectionClient::terminateServiceDiscovery(void)
00583 {
00584   _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED;
00585 
00586   if (terminationCallback) {
00587     terminationCallback(_connectionHandle);
00588   }
00589 }
00590 
00591 void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value)
00592 {
00593   // copy the data read, they will be forwarded to the user once the procedure
00594   // has completed
00595   readCBParams.connHandle = _connectionHandle;
00596   readCBParams.offset = 0;
00597   readCBParams.len = event_data_length;
00598   readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length));
00599   memcpy((void*)(readCBParams.data), attribute_value, event_data_length);
00600 }
00601 
00602 ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const
00603 {
00604   /* avoid compiler warnings about unused variables */
00605   (void)offset;
00606 
00607   tBleStatus ret;
00608 
00609   BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this);
00610 
00611   // Save the attribute_handle not provided by evt_att_read_resp
00612   gattc->readCBParams.handle = attributeHandle;
00613 
00614   ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle);
00615 
00616   if(ret == BLE_STATUS_SUCCESS) {
00617     gattc->_currentState = GATT_READ_CHAR;
00618     return BLE_ERROR_NONE;
00619   }
00620   switch (ret) {
00621   case ERR_CONTROLLER_BUSY:
00622     return BLE_STACK_BUSY;
00623   default:
00624     return BLE_ERROR_INVALID_STATE;
00625   }
00626 }
00627 
00628 void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length,
00629                                                      uint16_t attribute_handle,
00630                                                      uint16_t offset,
00631                                                      uint8_t *part_attr_value)
00632 {
00633   // Update the write response params
00634   writeCBParams.handle = attribute_handle;
00635   writeCBParams.offset = offset;
00636   writeCBParams.len = event_data_length-4; //(?)
00637   writeCBParams.data = part_attr_value;
00638 
00639   BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
00640 }
00641 
00642 void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length)
00643 {
00644   /* avoid compiler warnings about unused variables */
00645   (void)event_data_length;
00646 
00647   writeCBParams.connHandle = _connectionHandle;
00648 
00649   BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
00650 }
00651 
00652 ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t    cmd,
00653                                      GattAttribute::Handle_t  attributeHandle,
00654                                      size_t                   length,
00655                                      const uint8_t           *value) const
00656 {
00657   /* avoid compiler warnings about unused variables */
00658   (void)cmd;
00659   uint8_t flag=0; //1 if charHandle found, or 0
00660   tBleStatus ret;
00661 
00662   BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this);
00663 
00664   // We save the write response params (used by the callback) because
00665   // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE
00666   gattc->writeCBParams.connHandle = _connectionHandle;
00667   gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD;
00668   gattc->writeCBParams.handle = attributeHandle;
00669   gattc->writeCBParams.offset = 0;
00670   gattc->writeCBParams.len = length;
00671   gattc->writeCBParams.data = value;
00672   
00673   
00674   
00675 
00676 //------------------------------------------------------------------------------
00677 //Edited
00678 
00679 
00680   for (unsigned i=0; i<BLE_TOTAL_DISCOVERED_CHARS; i++){
00681     if (attributeHandle == discoveredChar[i].getDeclHandle()){
00682         flag = 1;
00683         break;
00684     }
00685     //else flag = 0
00686   }
00687 
00688 
00689 
00690 
00691   //if flag = 1 write characteristic
00692   if (flag == 1){
00693     if (cmd == GattClient::GATT_OP_WRITE_REQ){
00694         //with response (cmd = GattClient::GATT_OP_WRITE_REQ)
00695         ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value));
00696 
00697     }else {
00698         //without response (cmd = GattClient::GATT_OP_WRITE_CMD)
00699         ret = aci_gatt_write_without_response(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value));
00700     }
00701 
00702   //if flag = 0 write descriptor
00703   }else {
00704 
00705     if (cmd == GattClient::GATT_OP_WRITE_REQ){
00706         //with response (cmd = GattClient::GATT_OP_WRITE_REQ)
00707         ret = aci_gatt_write_charac_descriptor(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value));
00708 
00709     }else {
00710         //without response (cmd = GattClient::GATT_OP_WRITE_CMD)
00711         ret = aci_gatt_write_without_response(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value));
00712     }
00713   }
00714 
00715 //------------------------------------------------------------------------------
00716   
00717   
00718   
00719 
00720 
00721 
00722   if (ret == BLE_STATUS_SUCCESS) {
00723     gattc->_currentState = GATT_WRITE_CHAR;
00724     return BLE_ERROR_NONE;
00725   }
00726   switch (ret) {
00727   case ERR_CONTROLLER_BUSY:
00728     return BLE_STACK_BUSY;
00729   default:
00730     return BLE_ERROR_INVALID_STATE;
00731   }
00732 
00733 }
00734 
00735 void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length,
00736                                                       uint8_t format,
00737                                                       uint8_t *handle_uuid_pair) {
00738   GattAttribute::Handle_t attHandle;
00739   UUID uuid;
00740   uint8_t i, numCharacDesc, offset, handle_uuid_length;
00741 
00742   handle_uuid_length = 4; //Handle + UUID_16
00743   if (format == 2)
00744     handle_uuid_length = 18; //Handle + UUID_128
00745 
00746   numCharacDesc = (event_data_length - 1) / handle_uuid_length;
00747 
00748   offset = 0;
00749 
00750   PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n",
00751     event_data_length, format);
00752 
00753 
00754   for (i=0; i<numCharacDesc; i++) {
00755     memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle));
00756 
00757     // UUID Type
00758     if (handle_uuid_length == 4) {
00759 
00760       PRINTF("UUID_TYPE_16\n\r");
00761       uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2];
00762       PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle);
00763 
00764     } else {
00765 
00766       PRINTF("UUID_TYPE_128\n\r");
00767       uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB);
00768 #ifdef DEBUG
00769       PRINTF("D UUID-");
00770       const uint8_t *longUUIDBytes = uuid.getBaseUUID();
00771       for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) {
00772         PRINTF("%02x", longUUIDBytes[j]);
00773       }
00774 #endif
00775      }
00776 
00777      if(charDescDiscoveryCallback != NULL) {
00778        CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = {
00779                                  _characteristic,
00780                                  DiscoveredCharacteristicDescriptor(
00781                                    _characteristic.getGattClient(),
00782                                    _connectionHandle,
00783                                    attHandle,
00784                                    uuid
00785                                  )
00786        };
00787        charDescDiscoveryCallback(&params);
00788      }
00789 
00790     _numCharDesc++;
00791 
00792     offset += handle_uuid_length;
00793   }
00794 }
00795 
00796 ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors(
00797         const DiscoveredCharacteristic& characteristic,
00798         const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
00799         const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) {
00800 
00801   tBleStatus ret;
00802 
00803   if(_currentState != GATT_IDLE) {
00804     return BLE_ERROR_OPERATION_NOT_PERMITTED;
00805   }
00806 
00807   charDescDiscoveryCallback = discoveryCallback;
00808   charDescTerminationCallback = terminationCallback;
00809 
00810   GattAttribute::Handle_t valueHandle = characteristic.getValueHandle();
00811   GattAttribute::Handle_t lastHandle = characteristic.getLastHandle();
00812 
00813   PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle);
00814   ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle);
00815 
00816   if (ret == BLE_STATUS_SUCCESS) {
00817     _currentState = GATT_CHAR_DESC_DISCOVERY;
00818     _characteristic = characteristic;
00819     return BLE_ERROR_NONE;
00820   }
00821   switch (ret) {
00822   case BLE_STATUS_INVALID_PARAMS:
00823     return BLE_ERROR_INVALID_PARAM;
00824   default:
00825     return BLE_ERROR_OPERATION_NOT_PERMITTED;
00826   }
00827 }
00828 
00829 /**************************************************************************/
00830 /*!
00831     @brief  Clear BlueNRGGattServer's state.
00832 
00833     @returns    ble_error_t
00834 
00835     @retval     BLE_ERROR_NONE
00836                 Everything executed properly
00837 */
00838 /**************************************************************************/
00839 ble_error_t BlueNRGGattConnectionClient::reset(void) {
00840   PRINTF("BlueNRGGattConnectionClient::reset\n");
00841 
00842   /* Clear all state, including private members */
00843 
00844   _currentState = GATT_IDLE;
00845   _matchingServiceUUID = BLE_UUID_UNKNOWN;
00846   _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN;
00847 
00848   _numServices = 0;
00849   _servIndex = 0;
00850   _numChars = 0;
00851   _numCharDesc = 0;
00852 
00853   /* Clear class members */
00854   memset(discoveredService, 0, sizeof(discoveredService));
00855   memset(discoveredChar, 0, sizeof(discoveredChar));
00856 
00857   // free response if allocated
00858   if(readCBParams.data) {
00859     free((void*)(readCBParams.data));
00860   }
00861 
00862   return BLE_ERROR_NONE;
00863 }