tset

Fork of X_NUCLEO_IDB0XA1 by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BlueNRGGattClient.cpp Source File

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