text: /* 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.
   */
  
  #ifndef MBED_GATT_SERVER_H__
  #define MBED_GATT_SERVER_H__
  
  #include "ble/common/StaticInterface.h"
  #include "ble/GattService.h"
  #include "ble/GattAttribute.h"
  #include "ble/GattServerEvents.h"
  #include "ble/GattCallbackParamTypes.h"
  #include "ble/CallChainOfFunctionPointersWithContext.h"
  #include "BleImplementationForward.h"
  
  #if !defined(DOXYGEN_ONLY)
  namespace ble {
  namespace interface {
  #endif
  
  /**
   * @addtogroup ble
   * @{
   * @addtogroup gatt
   * @{
   * @addtogroup server
   * @{
   */
  
  /**
   * Construct and operates a GATT server.
   *
   * A Gatt server is a collection of GattService; these services contain
   * characteristics that a peer connected to the device may read or write.
   * These characteristics may also emit updates to subscribed clients when their
   * values change.
   *
   * @p Server Layout
   *
   * Application code can add a GattService object to the server with the help of
   * the function addService(). That function registers all the GattCharacteristic
   * enclosed in the service, as well as all the characteristics descriptors (see
   * GattAttribute) these characteristics contain. Service registration assigns
   * a unique handle to the various attributes being part of the service; this
   * handle should be used for subsequent read or write of these components.
   *
   * There are no primitives defined to remove a single service; however, a call to
   * the function reset() removes all services previously registered in the
   * GattServer.
   *
   * @p Characteristic and attributes access
   *
   * Values of the characteristic and the characteristic descriptor present in the
   * GattServer must be accessed through the handle assigned to them when the service
   * has been registered; the GattServer class offers several flavors of read()
   * and write() functions that retrieve or mutate an attribute value.
   *
   * Application code can query if a client has subscribed to a given
   * characteristic's value update by invoking the function areUpdatesEnabled().
   *
   * @p Events
   *
   * The GattServer allows application code to register several event handlers that
   * can be used to monitor client and server activities:
   *   - onDataSent(): Register an event handler that is called when a
   *     characteristic value update has been sent to a client.
   *   - onDataWriten(): Register an event handler that is called when a
   *     client has written an attribute of the server.
   *   - onDataRead(): Register an event handler that is called when a
   *     client has read an attribute of the server.
   *   - onUpdatesEnabled: Register an event handler that is called when a
   *     client subscribes to updates of a characteristic.
   *   - onUpdatesDisabled: Register an event handler that is called when a
   *     client unsubscribes from updates of a characteristic.
   *   - onConfimationReceived: Register an event handler that is called
   *     when a client acknowledges a characteristic value notification.
   *
   * @note The term characteristic value update is used to represent
   * Characteristic Value Notification and Characteristic Value Indication when
   * the nature of the server initiated is not relevant.
   */
  #if !defined(DOXYGEN_ONLY)
  template <class Impl>
  class GattServer : public StaticInterface<Impl, GattServer> {
  #else
  class GattServer {
  #endif
  
      using StaticInterface<Impl, ::ble::interface::GattServer>::impl;
  
  public:
  
      /**
       * Definition of the general handler of GattServer related events.
       */
      struct EventHandler {
          /**
           * Function invoked when the connections changes the ATT_MTU which controls
           * the maximum size of an attribute that can be read in a single L2CAP packet
           * which might be fragmented across multiple packets.
           *
           * @param connectionHandle The handle of the connection that changed the size.
           * @param attMtuSize
           */
          virtual void onAttMtuChange(
              ble::connection_handle_t connectionHandle,
              uint16_t attMtuSize
          )
          {
          }
      };
  
      /**
       * Assign the event handler implementation that will be used by the
       * module to signal events back to the application.
       *
       * @param handler Application implementation of an EventHandler.
       */
      void setEventHandler(EventHandler *handler)
      {
          eventHandler = handler;
      }
  
      /**
       * Event handler invoked when the server has sent data to a client.
       *
       * @see onDataSent().
       */
      typedef FunctionPointerWithContext<unsigned> DataSentCallback_t;
  
      /**
       * Callchain of DataSentCallback_t objects.
       *
       * @see onDataSent().
       */
      typedef CallChainOfFunctionPointersWithContext<unsigned>
          DataSentCallbackChain_t;
  
      /**
       * Event handler invoked when the client has written an attribute of the
       * server.
       *
       * @see onDataWritten().
       */
      typedef FunctionPointerWithContext<const GattWriteCallbackParams*>
          DataWrittenCallback_t;
  
      /**
       * Callchain of DataWrittenCallback_t objects.
       *
       * @see onDataWritten().
       */
      typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*>
          DataWrittenCallbackChain_t;
  
      /**
       * Event handler invoked when the client has read an attribute of the server.
       *
       * @see onDataRead().
       */
      typedef FunctionPointerWithContext<const GattReadCallbackParams*>
          DataReadCallback_t;
  
      /**
       * Callchain of DataReadCallback_t.
       *
       * @see onDataRead().
       */
      typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams*>
          DataReadCallbackChain_t;
  
      /**
       * Event handler invoked when the GattServer is reset.
       *
       * @see onShutdown() reset()
       */
      typedef FunctionPointerWithContext<const GattServer *>
          GattServerShutdownCallback_t;
  
      /**
       * Callchain of GattServerShutdownCallback_t.
       *
       * @see onShutdown() reset()
       */
      typedef CallChainOfFunctionPointersWithContext<const GattServer*>
          GattServerShutdownCallbackChain_t;
  
      /**
       * Event handler that handles subscription to characteristic updates,
       * unsubscription from characteristic updates and notification confirmation.
       *
       * @see onUpdatesEnabled() onUpdateDisabled() onConfirmationReceived()
       */
      typedef FunctionPointerWithContext<GattAttribute::Handle_t> EventCallback_t;
  
  protected:
      /**
       * Construct a GattServer instance.
       */
      GattServer();
  
      /*
       * The following functions are meant to be overridden in the platform
       * specific subclass.
       */
  public:
  
      /**
       * Add a service declaration to the local attribute server table.
       *
       * This functions inserts a service declaration in the attribute table
       * followed by the characteristic declarations (including characteristic
       * descriptors) present in @p service.
       *
       * The process assigns a unique attribute handle to all the elements added
       * into the attribute table. This handle is an ID that must be used for
       * subsequent interractions with the elements.
       *
       * @note There is no mirror function that removes a single service.
       * Application code can remove all the registered services by calling
       * reset().
       *
       * @attention Service, characteristics and descriptors objects registered
       * within the GattServer must remain reachable until reset() is called.
       *
       * @param[in] service The service to be added; attribute handle of services,
       * characteristic and characteristic descriptors are updated by the
       * process.
       *
       * @return BLE_ERROR_NONE if the service was successfully added.
       */
      ble_error_t addService(GattService &service);
  
      /**
       * Read the value of an attribute present in the local GATT server.
       *
       * @param[in] attributeHandle Handle of the attribute to read.
       * @param[out] buffer A buffer to hold the value being read.
       * @param[in,out] lengthP Length of the buffer being supplied. If the
       * attribute value is longer than the size of the supplied buffer, this
       * variable holds upon return the total attribute value length (excluding
       * offset). The application may use this information to allocate a suitable
       * buffer size.
       *
       * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
       *
       * @attention read(ble::connection_handle_t, GattAttribute::Handle_t, uint8_t *, uint16_t *)
       * must be used to read Client Characteristic Configuration Descriptor (CCCD)
       * because the value of this type of attribute depends on the connection.
       */
      ble_error_t read(
          GattAttribute::Handle_t attributeHandle,
          uint8_t buffer[],
          uint16_t *lengthP
      );
  
      /**
       * Read the value of an attribute present in the local GATT server.
       *
       * The connection handle allows application code to read the value of a
       * Client Characteristic Configuration Descriptor for a given connection.
       *
       * @param[in] connectionHandle Connection handle.
       * @param[in] attributeHandle Attribute handle for the value attribute of
       * the characteristic.
       * @param[out] buffer A buffer to hold the value being read.
       * @param[in,out] lengthP Length of the buffer being supplied. If the
       * attribute value is longer than the size of the supplied buffer, this
       * variable holds upon return the total attribute value length (excluding
       * offset). The application may use this information to allocate a suitable
       * buffer size.
       *
       * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
       */
      ble_error_t read(
          ble::connection_handle_t connectionHandle,
          GattAttribute::Handle_t attributeHandle,
          uint8_t *buffer,
          uint16_t *lengthP
      );
  
      /**
       * Update the value of an attribute present in the local GATT server.
       *
       * @param[in] attributeHandle Handle of the attribute to write.
       * @param[in] value A pointer to a buffer holding the new value.
       * @param[in] size Size in bytes of the new value (in bytes).
       * @param[in] localOnly If this flag is false and the attribute handle
       * written is a characteristic value, then the server sends an update
       * containing the new value to all clients that have subscribed to the
       * characteristic's notifications or indications. Otherwise, the update does
       * not generate a single server initiated event.
       *
       * @return BLE_ERROR_NONE if the attribute value has been successfully
       * updated.
       */
      ble_error_t write(
          GattAttribute::Handle_t attributeHandle,
          const uint8_t *value,
          uint16_t size,
          bool localOnly = false
      );
  
      /**
       * Update the value of an attribute present in the local GATT server.
       *
       * The connection handle parameter allows application code to direct
       * notification or indication resulting from the update to a specific client.
       *
       * @param[in] connectionHandle Connection handle.
       * @param[in] attributeHandle Handle for the value attribute of the
       * characteristic.
       * @param[in] value A pointer to a buffer holding the new value.
       * @param[in] size Size of the new value (in bytes).
       * @param[in] localOnly If this flag is false and the attribute handle
       * written is a characteristic value, then the server sends an update
       * containing the new value to the client identified by the parameter
       * @p connectionHandle if it is subscribed to the characteristic's
       * notifications or indications. Otherwise, the update does not generate a
       * single server initiated event.
       *
       * @return BLE_ERROR_NONE if the attribute value has been successfully
       * updated.
       */
      ble_error_t write(
          ble::connection_handle_t connectionHandle,
          GattAttribute::Handle_t attributeHandle,
          const uint8_t *value,
          uint16_t size,
          bool localOnly = false
      );
  
      /**
       * Determine if one of the connected clients has subscribed to notifications
       * or indications of the characteristic in input.
       *
       * @param[in] characteristic The characteristic.
       * @param[out] enabledP Upon return, *enabledP is true if updates are
       * enabled for a connected client; otherwise, *enabledP is false.
       *
       * @return BLE_ERROR_NONE if the connection and handle are found. False
       * otherwise.
       */
      ble_error_t areUpdatesEnabled(
          const GattCharacteristic &characteristic,
          bool *enabledP
      );
  
      /**
       * Determine if an identified client has subscribed to notifications or
       * indications of a given characteristic.
       *
       * @param[in] connectionHandle The connection handle.
       * @param[in] characteristic The characteristic.
       * @param[out] enabledP Upon return, *enabledP is true if the client
       * identified by @p connectionHandle has subscribed to notifications or
       * indications of @p characteristic; otherwise, *enabledP is false.
       *
       * @return BLE_ERROR_NONE if the connection and handle are found. False
       * otherwise.
       */
      ble_error_t areUpdatesEnabled(
          ble::connection_handle_t connectionHandle,
          const GattCharacteristic &characteristic,
          bool *enabledP
      );
  
      /**
       * Indicate if the underlying stack emit events when an attribute is read by
       * a client.
       *
       * @attention This function should be overridden to return true if
       * applicable.
       *
       * @return true if onDataRead is supported; false otherwise.
       */
      bool isOnDataReadAvailable() const;
  
      /*
       * APIs with nonvirtual implementations.
       */
  public:
      /**
       * Add an event handler that monitors emission of characteristic value
       * updates.
       *
       * @param[in] callback Event handler being registered.
       *
       * @note It is possible to chain together multiple onDataSent callbacks
       * (potentially from different modules of an application).
       */
      void onDataSent(const DataSentCallback_t &callback)
      {
          dataSentCallChain.add(callback);
      }
  
      /**
       * Add an event handler that monitors emission of characteristic value
       * updates.
       *
       * @param[in] objPtr Pointer to the instance that is used to invoke the
       * event handler.
       * @param[in] memberPtr Event handler being registered. It is a member
       * function.
       */
      template <typename T>
      void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count))
      {
          dataSentCallChain.add(objPtr, memberPtr);
      }
  
      /**
       * Access the callchain of data sent event handlers.
       *
       * @return A reference to the DATA_SENT event callback chain.
       */
      DataSentCallbackChain_t &onDataSent()
      {
          return dataSentCallChain;
      }
  
      /**
       * Set an event handler that is called after
       * a connected peer has written an attribute.
       *
       * @param[in] callback The event handler being registered.
       *
       * @attention It is possible to set multiple event handlers. Registered
       * handlers may be removed with onDataWritten().detach(callback).
       */
      void onDataWritten(const DataWrittenCallback_t &callback)
      {
          dataWrittenCallChain.add(callback);
      }
  
      /**
       * Set an event handler that is called after
       * a connected peer has written an attribute.
       *
       * @param[in] objPtr Pointer to the instance that is used to invoke the
       * event handler (@p memberPtr).
       * @param[in] memberPtr Event handler being registered. It is a member
       * function.
       */
      template <typename T>
      void onDataWritten(
          T *objPtr,
          void (T::*memberPtr)(const GattWriteCallbackParams *context)
      ) {
          dataWrittenCallChain.add(objPtr, memberPtr);
      }
  
      /**
       * Access the callchain of data written event handlers.
       *
       * @return A reference to the data written event callbacks chain.
       *
       * @note It is possible to register callbacks using
       * onDataWritten().add(callback).
       *
       * @note It is possible to unregister callbacks using
       * onDataWritten().detach(callback).
       */
      DataWrittenCallbackChain_t &onDataWritten()
      {
          return dataWrittenCallChain;
      }
  
      /**
       * Set an event handler that monitors attribute reads from connected clients.
       *
       * @param[in] callback Event handler being registered.
       *
       * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
       * else BLE_ERROR_NONE.
       *
       * @note  This functionality may not be available on all underlying stacks.
       * Application code may work around that limitation by monitoring read
       * requests instead of read events.
       *
       * @see GattCharacteristic::setReadAuthorizationCallback()
       * @see isOnDataReadAvailable().
       *
       * @attention It is possible to set multiple event handlers. Registered
       * handlers may be removed with onDataRead().detach(callback).
       */
      ble_error_t onDataRead(const DataReadCallback_t &callback)
      {
          if (!isOnDataReadAvailable()) {
              return BLE_ERROR_NOT_IMPLEMENTED;
          }
  
          dataReadCallChain.add(callback);
          return BLE_ERROR_NONE;
      }
  
      /**
       * Set an event handler that monitors attribute reads from connected clients.
       *
       * @param[in] objPtr Pointer to the instance that is used to invoke the
       * event handler (@p memberPtr).
       * @param[in] memberPtr Event handler being registered. It is a member
       * function.
       */
      template <typename T>
      ble_error_t onDataRead(
          T *objPtr,
          void (T::*memberPtr)(const GattReadCallbackParams *context)
      ) {
          if (!isOnDataReadAvailable()) {
              return BLE_ERROR_NOT_IMPLEMENTED;
          }
  
          dataReadCallChain.add(objPtr, memberPtr);
          return BLE_ERROR_NONE;
      }
  
      /**
       * Access the callchain of data read event handlers.
       *
       * @return A reference to the data read event callbacks chain.
       *
       * @note It is possible to register callbacks using
       * onDataRead().add(callback).
       *
       * @note It is possible to unregister callbacks using
       * onDataRead().detach(callback).
       */
      DataReadCallbackChain_t &onDataRead()
      {
          return dataReadCallChain;
      }
  
      /**
       * Set an event handler that monitors shutdown or reset of the GattServer.
       *
       * The event handler is invoked when the GattServer instance is about
       * to be shut down. This can result in a call to reset() or BLE::reset().
       *
       * @param[in] callback Event handler being registered.
       *
       * @note It is possible to set up multiple shutdown event handlers.
       *
       * @note It is possible to unregister a callback using
       * onShutdown().detach(callback)
       */
      void onShutdown(const GattServerShutdownCallback_t &callback)
      {
          shutdownCallChain.add(callback);
      }
  
      /**
       * Set an event handler that monitors shutdown or reset of the GattServer.
       *
       * The event handler is invoked when the GattServer instance is about
       * to be shut down. This can result of a call to reset() or BLE::reset().
       *
       * @param[in] objPtr Pointer to the instance that is used to invoke the
       * event handler (@p memberPtr).
       * @param[in] memberPtr Event handler being registered. It is a member
       * function.
       */
      template <typename T>
      void onShutdown(T *objPtr, void (T::*memberPtr)(const GattServer *))
      {
          shutdownCallChain.add(objPtr, memberPtr);
      }
  
      /**
       * Access the callchain of shutdown event handlers.
       *
       * @return A reference to the shutdown event callbacks chain.
       *
       * @note It is possible to register callbacks using
       * onShutdown().add(callback).
       *
       * @note It is possible to unregister callbacks using
       * onShutdown().detach(callback).
       */
      GattServerShutdownCallbackChain_t& onShutdown()
      {
          return shutdownCallChain;
      }
  
      /**
       * Set up an event handler that monitors subscription to characteristic
       * updates.
       *
       * @param[in] callback Event handler being registered.
       */
      void onUpdatesEnabled(EventCallback_t callback)
      {
          updatesEnabledCallback = callback;
      }
  
      /**
       * Set up an event handler that monitors unsubscription from characteristic
       * updates.
       *
       * @param[in] callback Event handler being registered.
       */
      void onUpdatesDisabled(EventCallback_t callback)
      {
          updatesDisabledCallback = callback;
      }
  
      /**
       * Set up an event handler that monitors notification acknowledgment.
       *
       * The event handler is called when a client sends a confirmation that it has
       * correctly received a notification from the server.
       *
       * @param[in] callback Event handler being registered.
       */
      void onConfirmationReceived(EventCallback_t callback)
      {
          confirmationReceivedCallback = callback;
      }
  
      /* Entry points for the underlying stack to report events back to the user. */
  protected:
      /**
       * Helper function that notifies all registered handlers of an occurrence
       * of a data written event.
       *
       * @attention Vendor implementation must invoke this function after one of
       * the GattServer attributes has been written.
       *
       * @param[in] params The data written parameters passed to the registered
       * handlers.
       */
      void handleDataWrittenEvent(const GattWriteCallbackParams *params)
      {
          dataWrittenCallChain.call(params);
      }
  
      /**
       * Helper function that notifies all registered handlers of an occurrence
       * of a data read event.
       *
       * @attention Vendor implementation must invoke this function after one of
       * the GattServer attributes has been read.
       *
       * @param[in] params The data read parameters passed to the registered
       * handlers.
       */
      void handleDataReadEvent(const GattReadCallbackParams *params)
      {
          dataReadCallChain.call(params);
      }
  
      /**
       * Helper function that notifies the registered handler of an occurrence
       * of updates enabled, updates disabled or confirmation received events.
       *
       * @attention Vendor implementation must invoke this function when a client
       * subscribes to characteristic updates, unsubscribes from characteristic
       * updates or a notification confirmation has been received.
       *
       * @param[in] type The type of event that occurred.
       * @param[in] attributeHandle The handle of the attribute concerned by the
       * event.
       */
      void handleEvent(
          GattServerEvents::gattEvent_e type,
          GattAttribute::Handle_t attributeHandle
      ) {
          switch (type) {
              case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
                  if (updatesEnabledCallback) {
                      updatesEnabledCallback(attributeHandle);
                  }
                  break;
              case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
                  if (updatesDisabledCallback) {
                      updatesDisabledCallback(attributeHandle);
                  }
                  break;
              case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
                  if (confirmationReceivedCallback) {
                      confirmationReceivedCallback(attributeHandle);
                  }
                  break;
  
              case GattServerEvents::GATT_EVENT_DATA_SENT:
                  // Called every time a notification or indication has been sent
                  handleDataSentEvent(1);
                  break;
  
              default:
                  break;
          }
      }
  
      /**
       * Helper function that notifies all registered handlers of an occurrence
       * of a data sent event.
       *
       * @attention Vendor implementation must invoke this function after the
       * emission of a notification or an indication.
       *
       * @param[in] count Number of packets sent.
       */
      void handleDataSentEvent(unsigned count)
      {
          dataSentCallChain.call(count);
      }
  
  public:
      /**
       * Shut down the GattServer instance.
       *
       * This function notifies all event handlers listening for shutdown events
       * that the GattServer is about to be shut down; then it clears all
       * GattServer state.
       *
       * @note This function is meant to be overridden in the platform-specific
       * subclass. Overides must call the parent function before any cleanup.
       *
       * @return BLE_ERROR_NONE on success.
       */
      ble_error_t reset(void);
  
  protected:
      /* --- Abstract calls to override --- */
  
      /* Derived implementation must call the base reset_ */
      ble_error_t reset_(void);
  
      ble_error_t addService_(GattService &service);
  
      ble_error_t read_(
          GattAttribute::Handle_t attributeHandle,
          uint8_t buffer[],
          uint16_t *lengthP
      );
  
      ble_error_t read_(
          ble::connection_handle_t connectionHandle,
          GattAttribute::Handle_t attributeHandle,
          uint8_t *buffer,
          uint16_t *lengthP
      );
  
      ble_error_t write_(
          GattAttribute::Handle_t attributeHandle,
          const uint8_t *value,
          uint16_t size,
          bool localOnly
      );
  
      ble_error_t write_(
          ble::connection_handle_t connectionHandle,
          GattAttribute::Handle_t attributeHandle,
          const uint8_t *value,
          uint16_t size,
          bool localOnly
      );
  
      ble_error_t areUpdatesEnabled_(
          const GattCharacteristic &characteristic,
          bool *enabledP
      );
  
      ble_error_t areUpdatesEnabled_(
          ble::connection_handle_t connectionHandle,
          const GattCharacteristic &characteristic,
          bool *enabledP
      );
  
      bool isOnDataReadAvailable_() const;
  
  protected:
      /**
       * Event handler provided by the application.
       */
      EventHandler *eventHandler;
  
      /**
       * The total number of services added to the ATT table.
       */
      uint8_t serviceCount;
  
      /**
       * The total number of characteristics added to the ATT table.
       */
      uint8_t characteristicCount;
  
  private:
      /**
       * Callchain containing all registered callback handlers for data sent
       * events.
       */
      DataSentCallbackChain_t dataSentCallChain;
  
      /**
       * Callchain containing all registered callback handlers for data written
       * events.
       */
      DataWrittenCallbackChain_t dataWrittenCallChain;
  
      /**
       * Callchain containing all registered callback handlers for data read
       * events.
       */
      DataReadCallbackChain_t dataReadCallChain;
  
      /**
       * Callchain containing all registered callback handlers for shutdown
       * events.
       */
      GattServerShutdownCallbackChain_t shutdownCallChain;
  
      /**
       * The registered callback handler for updates enabled events.
       */
      EventCallback_t updatesEnabledCallback;
  
      /**
       * The registered callback handler for updates disabled events.
       */
      EventCallback_t updatesDisabledCallback;
  
      /**
       * The registered callback handler for confirmation received events.
       */
      EventCallback_t confirmationReceivedCallback;
  
  private:
      /* Disallow copy and assignment. */
      GattServer(const GattServer &);
      GattServer& operator=(const GattServer &);
  };
  
  /**
   * @}
   * @}
   * @}
   */
  
  #if !defined(DOXYGEN_ONLY)
  } // interface
  } // ble
  
  typedef ble::impl::GattServer GattServer;
  
  #endif
  
  
  #endif /* ifndef MBED_GATT_SERVER_H__ */
  