Fork of ble-x-nucleo-idb0xa1 with changes required by BleStarMbed

Dependents:   ble-star-mbed

Revision:
0:ac0b0725c6fa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRGGattClient.cpp	Tue Feb 20 11:07:16 2018 +0000
@@ -0,0 +1,403 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+  ******************************************************************************
+  * @file    BlueNRGGattServer.cpp
+  * @author  STMicroelectronics
+  * @brief   Implementation of BlueNRG BLE_API GattServer Class
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */
+
+/** @defgroup BlueNRGGATTClient
+ *  @brief BlueNRG BLE_API GattClient Adaptation
+ *  @{
+ */
+
+#include "BlueNRGGattClient.h"
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif 
+#include "BlueNRGGap.h"
+#include "ble_utils.h"
+#include "ble_debug.h"
+
+#include <new>
+#include <assert.h>
+
+ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle)
+{
+  if(MAX_ACTIVE_CONNECTIONS <= _numConnections) {
+    return BLE_ERROR_OPERATION_NOT_PERMITTED;
+  }
+
+  for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+
+    if(_connectionPool[i] == NULL) {
+      BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle);
+
+      if (gattConnectionClient == NULL) {
+        return BLE_ERROR_NO_MEM;
+      }
+
+      _connectionPool[i] = gattConnectionClient;
+      _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback);
+      _numConnections++;
+
+      PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i);
+      PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections);
+      break;
+    }
+  }
+
+  return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason)
+{
+
+  PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason);
+
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+    PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle);
+
+    if(_connectionPool[i]->_connectionHandle == connectionHandle) {
+      PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n");
+      delete _connectionPool[i];
+      _connectionPool[i] = NULL;
+
+      _numConnections--;
+      PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections);
+
+      break;
+
+    } else {
+      return BLE_ERROR_INTERNAL_STACK_FAILURE;
+    }
+  }
+
+  return BLE_ERROR_NONE;
+}
+
+BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) {
+  PRINTF("getGattConnectionClient\r\n");
+
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+    PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle);
+
+    if(_connectionPool[i]->_connectionHandle == connectionHandle) {
+      PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n");
+      return _connectionPool[i];
+    }
+  }
+
+  return NULL;
+}
+
+void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) {
+
+  if(error_code != BLE_STATUS_SUCCESS) {
+    return;
+  }
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->gattProcedureCompleteCB(error_code);
+}
+
+void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle,
+                                          uint8_t event_data_length,
+                                          uint8_t attribute_data_length,
+                                          uint8_t *attribute_data_list) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->primaryServicesCB(event_data_length,
+                                          attribute_data_length,
+                                          attribute_data_list);
+}
+    
+void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle,
+                                         uint8_t event_data_length,
+                                         uint8_t *handles_info_list) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->primaryServiceCB(event_data_length,
+                                         handles_info_list);
+}
+    
+ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  if(gattConnectionClient != NULL) {
+    return gattConnectionClient->findServiceChars();
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+    
+void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle,
+                                       uint8_t event_data_length,
+                                       uint8_t handle_value_pair_length,
+                                       uint8_t *handle_value_pair) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->serviceCharsCB(event_data_length,
+                                       handle_value_pair_length,
+                                       handle_value_pair);
+}
+    
+void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle,
+                                            uint8_t event_data_length,
+                                            uint16_t attr_handle,
+                                            uint8_t *attr_value) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->serviceCharByUUIDCB(event_data_length,
+                                            attr_handle,
+                                            attr_value);
+}
+
+void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle,
+                                            uint8_t event_data_length,
+                                            uint8_t format,
+                                            uint8_t *handle_uuid_pair) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->discAllCharacDescCB(event_data_length,
+                                            format,
+                                            handle_uuid_pair);
+}
+
+void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle,
+                                   uint8_t event_data_length,
+                                   uint8_t* attribute_value) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->charReadCB(event_data_length,
+                                   attribute_value);
+}
+
+void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle,
+                                           uint8_t event_data_length,
+                                           uint16_t attribute_handle,
+                                           uint16_t offset,
+                                           uint8_t *part_attr_value) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->charWritePrepareCB(event_data_length,
+                                           attribute_handle,
+                                           offset,
+                                           part_attr_value);
+}
+    
+void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle,
+                                        uint8_t event_data_length) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->charWriteExecCB(event_data_length);
+}
+
+ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t                               connectionHandle,
+                                                      ServiceDiscovery::ServiceCallback_t         sc,
+                                                      ServiceDiscovery::CharacteristicCallback_t  cc,
+                                                      const UUID                                 &matchingServiceUUID,
+                                                      const UUID                                 &matchingCharacteristicUUIDIn)
+{
+  PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r");
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  if(gattConnectionClient != NULL) {
+    return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn);
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t                        connectionHandle,
+                                                ServiceDiscovery::ServiceCallback_t  callback,
+                                                const UUID                          &matchingServiceUUID)
+{
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  if(gattConnectionClient != NULL) {
+
+    return gattConnectionClient->discoverServices(callback, matchingServiceUUID);
+
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t                        connectionHandle,
+                                                ServiceDiscovery::ServiceCallback_t  callback,
+                                                GattAttribute::Handle_t              startHandle,
+                                                GattAttribute::Handle_t              endHandle)
+{
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  if(gattConnectionClient != NULL) {
+
+    return gattConnectionClient->discoverServices(callback, startHandle, endHandle);
+
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+bool BlueNRGGattClient::isServiceDiscoveryActive(void) const
+{
+  bool isSDActive = false;
+
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+    if (_connectionPool[i]) { 
+      isSDActive |= _connectionPool[i]->isServiceDiscoveryActive();
+    }
+  }
+
+  return isSDActive;
+}
+
+void BlueNRGGattClient::terminateServiceDiscovery(void)
+{
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+    if (_connectionPool[i]) { 
+      _connectionPool[i]->terminateServiceDiscovery();
+    }
+  }
+}
+
+void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) {
+  terminationCallback = callback;
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) {
+    if (_connectionPool[i]) { 
+      _connectionPool[i]->onServiceDiscoveryTermination(callback);
+    }
+  }
+}
+
+ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const
+{
+  BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle);
+
+  if(gattConnectionClient != NULL) {
+
+    return gattConnectionClient->read(attributeHandle, offset);
+
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t    cmd,
+                                     Gap::Handle_t            connHandle,
+                                     GattAttribute::Handle_t  attributeHandle,
+                                     size_t                   length,
+                                     const uint8_t           *value) const
+{
+  BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle);
+
+  if(gattConnectionClient != NULL) {
+
+    return gattConnectionClient->write(cmd, attributeHandle, length, value);
+
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors(
+        const DiscoveredCharacteristic& characteristic,
+        const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+        const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback)
+{
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle());
+
+  if(gattConnectionClient != NULL) {
+
+    return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback);
+
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Clear BlueNRGGattClient's state.
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattClient::reset(void)
+{
+  PRINTF("BlueNRGGattClient::reset\n");
+
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+    if(_connectionPool[i] != NULL) {
+      _connectionPool[i]->reset();
+
+      delete _connectionPool[i];
+      _connectionPool[i] = NULL;
+
+      _numConnections--;
+    }
+  }
+
+  return BLE_ERROR_NONE;
+}
+