This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new a720984eb7 wireless/bluetooth: Add a generic access service.
a720984eb7 is described below

commit a720984eb7b1cabd259014df0d4e9ac0ef0e94dd
Author: Lwazi Dube <[email protected]>
AuthorDate: Fri Jun 2 22:47:14 2023 -0400

    wireless/bluetooth: Add a generic access service.
    
    Make NuttX peripheral visible to BLE apps.
---
 include/nuttx/wireless/bluetooth/bt_core.h |  16 ++
 wireless/bluetooth/Kconfig                 |  20 +++
 wireless/bluetooth/Make.defs               |   2 +-
 wireless/bluetooth/bt_netdev.c             |   9 +-
 wireless/bluetooth/bt_services.c           | 241 +++++++++++++++++++++++++++++
 5 files changed, 282 insertions(+), 6 deletions(-)

diff --git a/include/nuttx/wireless/bluetooth/bt_core.h 
b/include/nuttx/wireless/bluetooth/bt_core.h
index e13ef300fc..4b0f608965 100644
--- a/include/nuttx/wireless/bluetooth/bt_core.h
+++ b/include/nuttx/wireless/bluetooth/bt_core.h
@@ -217,4 +217,20 @@ static inline int bt_addr_le_to_str(FAR const bt_addr_le_t 
*addr, char *str,
  * Public Function Prototypes
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: bt_add_services
+ *
+ * Description:
+ *   Register services and start advertising.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero in case of success or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int bt_add_services(void);
+
 #endif /* __INCLUDE_NUTTX_WIRELESS_BLUETOOTH_BT_CORE_H */
diff --git a/wireless/bluetooth/Kconfig b/wireless/bluetooth/Kconfig
index bdef26498d..d5c60c2dc5 100644
--- a/wireless/bluetooth/Kconfig
+++ b/wireless/bluetooth/Kconfig
@@ -60,6 +60,26 @@ menuconfig WIRELESS_BLUETOOTH_HOST
                BLE link-layer or to an external device over HCI UART).
 
 if WIRELESS_BLUETOOTH_HOST
+config DEVICE_APPEARANCE
+       int "Appearance sub-category value"
+       default 0
+       range 0 5188
+       ---help---
+               This value comes from the "Appearance sub-category"
+               section (2.6.3) in the Bluetooth Assigned Numbers document.
+
+config DEVICE_NAME
+       string "Device name"
+       default "Apache NuttX"
+       ---help---
+               The device name.
+
+config DEVICE_LOCAL_NAME
+       string "Device local name"
+       default "NuttX"
+       ---help---
+               The device name used for advertising.
+
 endif # WIRELESS_BLUETOOTH_HOST
 
 config BLUETOOTH_MAX_CONN
diff --git a/wireless/bluetooth/Make.defs b/wireless/bluetooth/Make.defs
index e16fb7b08d..9df9daf468 100644
--- a/wireless/bluetooth/Make.defs
+++ b/wireless/bluetooth/Make.defs
@@ -30,7 +30,7 @@ ifeq ($(CONFIG_WIRELESS_BLUETOOTH_HOST),y)
 
 CSRCS += bt_atomic.c bt_att.c  bt_conn.c bt_gatt.c
 CSRCS += bt_ioctl.c bt_keys.c bt_l2cap.c bt_smp.c
-CSRCS += bt_uuid.c
+CSRCS += bt_uuid.c bt_services.c
 
 endif
 
diff --git a/wireless/bluetooth/bt_netdev.c b/wireless/bluetooth/bt_netdev.c
index a2b5d446eb..bcf30ba384 100644
--- a/wireless/bluetooth/bt_netdev.c
+++ b/wireless/bluetooth/bt_netdev.c
@@ -296,21 +296,18 @@ static void btnet_l2cap_connected(FAR struct bt_conn_s 
*conn,
                                   FAR void *context, uint16_t cid)
 {
   wlinfo("Connected\n");
-#warning Missing logic
 }
 
 static void btnet_l2cap_disconnected(FAR struct bt_conn_s *conn,
                                      FAR void *context, uint16_t cid)
 {
   wlinfo("Disconnected\n");
-#warning Missing logic
 }
 
 static void btnet_l2cap_encrypt_change(FAR struct bt_conn_s *conn,
                                        FAR void *context, uint16_t cid)
 {
   wlinfo("Encryption change\n");
-#warning Missing logic
 }
 
 /****************************************************************************
@@ -463,14 +460,12 @@ static void btnet_hci_connected(FAR struct bt_conn_s 
*conn,
                                 FAR void *context)
 {
   wlinfo("Connected\n");
-#warning Missing logic
 }
 
 static void btnet_hci_disconnected(FAR struct bt_conn_s *conn,
                                    FAR void *context)
 {
   wlinfo("Disconnected\n");
-#warning Missing logic
 }
 #else
 
@@ -1301,6 +1296,10 @@ int bt_netdev_register(FAR struct bt_driver_s *btdev)
   priv->bd_dev.r_dev.d_buf = g_iobuffer.rb_buf;
 #endif
 
+#ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
+  bt_add_services();
+#endif
+
   /* Register the network device with the OS so that socket IOCTLs can be
    * performed
    */
diff --git a/wireless/bluetooth/bt_services.c b/wireless/bluetooth/bt_services.c
new file mode 100644
index 0000000000..da754349d2
--- /dev/null
+++ b/wireless/bluetooth/bt_services.c
@@ -0,0 +1,241 @@
+/****************************************************************************
+ * wireless/bluetooth/bt_services.c
+ *
+ *   Copyright (c) 2016, Intel Corporation
+ *   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+#include <arpa/inet.h>
+#include <sys/param.h>
+
+#include <nuttx/wireless/bluetooth/bt_hci.h>
+#include <nuttx/wireless/bluetooth/bt_core.h>
+#include <nuttx/wireless/bluetooth/bt_uuid.h>
+#include <nuttx/wireless/bluetooth/bt_gatt.h>
+
+#include "bt_hcicore.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define GASVC                     0x0001
+#define NAME_CHR                  (GASVC + 0x0002)
+#define NAME_DSC                  (GASVC + 0x0003)
+#define APPEARANCE_CHR            (GASVC + 0x0004)
+#define APPEARANCE_DSC            (GASVC + 0x0005)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int read_appearance(FAR struct bt_conn_s *conn,
+                           FAR const struct bt_gatt_attr_s *attr,
+                           FAR void *buf,
+                           uint8_t len,
+                           uint16_t offset);
+
+static int read_name(FAR struct bt_conn_s *conn,
+                     FAR const struct bt_gatt_attr_s *attr,
+                     FAR void *buf,
+                     uint8_t len,
+                     uint16_t offset);
+
+static struct bt_uuid_s g_gap_uuid =
+{
+  .type  = BT_UUID_16,
+  .u     =
+  {
+    .u16 = BT_UUID_GAP
+  },
+};
+
+static struct bt_uuid_s g_device_name_uuid =
+{
+  .type  = BT_UUID_16,
+  .u     =
+  {
+    .u16 = BT_UUID_GAP_DEVICE_NAME,
+  }
+};
+
+static struct bt_gatt_chrc_s g_name_chrc =
+{
+  .properties   = BT_GATT_CHRC_READ,
+  .value_handle = NAME_DSC,
+  .uuid         = &g_device_name_uuid,
+};
+
+static struct bt_uuid_s g_appeareance_uuid =
+{
+  .type  = BT_UUID_16,
+  .u     =
+  {
+    .u16 = BT_UUID_GAP_APPEARANCE,
+  }
+};
+
+static struct bt_gatt_chrc_s g_appearance_chrc =
+{
+  .properties   = BT_GATT_CHRC_READ,
+  .value_handle = APPEARANCE_DSC,
+  .uuid         = &g_appeareance_uuid,
+};
+
+static const struct bt_gatt_attr_s g_attrs[] =
+{
+    BT_GATT_PRIMARY_SERVICE(GASVC, &g_gap_uuid),
+    BT_GATT_CHARACTERISTIC(NAME_CHR, &g_name_chrc),
+    BT_GATT_DESCRIPTOR(NAME_DSC, &g_device_name_uuid, BT_GATT_PERM_READ,
+                       read_name, NULL, (FAR void *)CONFIG_DEVICE_NAME),
+    BT_GATT_CHARACTERISTIC(APPEARANCE_CHR, &g_appearance_chrc),
+    BT_GATT_DESCRIPTOR(APPEARANCE_DSC, &g_appeareance_uuid,
+                       BT_GATT_PERM_READ, read_appearance, NULL, NULL),
+};
+
+static const struct bt_eir_s g_ad[] =
+{
+  {
+    .len  = 2,
+    .type = BT_EIR_FLAGS,
+    .data =
+    {
+      BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR
+    },
+  },
+  {
+    .len  = 0,
+    .type = 0,
+    .data = "",
+  }
+};
+
+static const struct bt_eir_s g_sd[] =
+{
+  {
+    .len  = 16,
+    .type = BT_EIR_NAME_COMPLETE,
+    .data = CONFIG_DEVICE_LOCAL_NAME,
+  },
+  {
+    .len  = 0,
+    .type = 0,
+    .data = "",
+  }
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: read_name
+ *
+ * Description:
+ *   Read callback for name descriptor.
+ *
+ * Returned Value:
+ *   Zero in case of success or negative value in case of error.
+ *
+ ****************************************************************************/
+
+static int read_name(FAR struct bt_conn_s *conn,
+                     FAR const struct bt_gatt_attr_s *attr,
+                     FAR void *buf,
+                     uint8_t len,
+                     uint16_t offset)
+{
+  FAR const char *name = attr->user_data;
+
+  return bt_gatt_attr_read(conn, attr, buf, len, offset, name,
+                           strlen(name));
+}
+
+/****************************************************************************
+ * Name: read_appearance
+ *
+ * Description:
+ *   Read callback for appearance descriptor.
+ *
+ * Returned Value:
+ *   Zero in case of success or negative value in case of error.
+ *
+ ****************************************************************************/
+
+static int read_appearance(FAR struct bt_conn_s *conn,
+                           FAR const struct bt_gatt_attr_s *attr,
+                           FAR void *buf,
+                           uint8_t len,
+                           uint16_t offset)
+{
+  uint16_t appearance = htole16(CONFIG_DEVICE_APPEARANCE);
+
+  return bt_gatt_attr_read(conn, attr, buf, len, offset, &appearance,
+                           sizeof(appearance));
+}
+
+/****************************************************************************
+ * Name: bt_add_services
+ *
+ * Description:
+ *   Register services and start advertising.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero in case of success or negative value in case of error.
+ *
+ ****************************************************************************/
+
+int bt_add_services(void)
+{
+  int err;
+
+  bt_gatt_register(g_attrs, nitems(g_attrs));
+
+  err = bt_start_advertising(BT_LE_ADV_IND, g_ad, g_sd);
+  if (err)
+    {
+      wlerr("Advertising failed to start (err %d)\n", err);
+    }
+
+  return err;
+}

Reply via email to