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

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


The following commit(s) were added to refs/heads/master by this push:
     new c6d7c896c examples/nimble_bleess: Add Environmental Sensing peripheral
c6d7c896c is described below

commit c6d7c896c2e0a9a34f2d432fbf9d90fdccd6e01a
Author: Jackson-gjh <[email protected]>
AuthorDate: Sat Nov 7 15:24:50 2026 +0800

    examples/nimble_bleess: Add Environmental Sensing peripheral
    
    Add a reusable NimBLE peripheral example for the standard Bluetooth
    Environmental Sensing service. The example exposes readable and
    notifiable Temperature and Humidity characteristics using their standard
    0.01-unit encodings.
    
    Generate slowly changing sample values so the example can be exercised
    without sensor hardware, while keeping the GATT update function available
    for integration with a real sensor.
    
    The example was built and run on ESP32-C6. A Bleak client discovered the
    service, read both characteristics, and received notifications from both.
    
    Assisted-by: Codex:gpt-5
    Signed-off-by: Jackson-gjh <[email protected]>
---
 examples/nimble_bleess/CMakeLists.txt       |  37 +++++
 examples/nimble_bleess/Kconfig              |  30 ++++
 examples/nimble_bleess/Make.defs            |  25 ++++
 examples/nimble_bleess/Makefile             |  34 +++++
 examples/nimble_bleess/bleess.h             |  59 ++++++++
 examples/nimble_bleess/bleess_gap.c         | 195 ++++++++++++++++++++++++++
 examples/nimble_bleess/bleess_gatt.c        | 210 ++++++++++++++++++++++++++++
 examples/nimble_bleess/nimble_bleess_main.c | 148 ++++++++++++++++++++
 8 files changed, 738 insertions(+)

diff --git a/examples/nimble_bleess/CMakeLists.txt 
b/examples/nimble_bleess/CMakeLists.txt
new file mode 100644
index 000000000..192e4bb20
--- /dev/null
+++ b/examples/nimble_bleess/CMakeLists.txt
@@ -0,0 +1,37 @@
+# 
##############################################################################
+# apps/examples/nimble_bleess/CMakeLists.txt
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more 
contributor
+# license agreements.  See the NOTICE file distributed with this work for
+# additional information regarding copyright ownership.  The ASF licenses this
+# file to you 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.
+#
+# 
##############################################################################
+
+if(CONFIG_EXAMPLES_NIMBLE_BLEESS)
+  nuttx_add_application(
+    NAME
+    ${CONFIG_EXAMPLES_NIMBLE_BLEESS_PROGNAME}
+    PRIORITY
+    ${CONFIG_EXAMPLES_NIMBLE_BLEESS_PRIORITY}
+    STACKSIZE
+    ${CONFIG_EXAMPLES_NIMBLE_BLEESS_STACKSIZE}
+    SRCS
+    ${CMAKE_CURRENT_LIST_DIR}/nimble_bleess_main.c
+    ${CMAKE_CURRENT_LIST_DIR}/bleess_gap.c
+    ${CMAKE_CURRENT_LIST_DIR}/bleess_gatt.c
+    DEPENDS
+    nimble)
+endif()
diff --git a/examples/nimble_bleess/Kconfig b/examples/nimble_bleess/Kconfig
new file mode 100644
index 000000000..013d9a91f
--- /dev/null
+++ b/examples/nimble_bleess/Kconfig
@@ -0,0 +1,30 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+config EXAMPLES_NIMBLE_BLEESS
+       tristate "NimBLE Environmental Sensing peripheral"
+       default n
+       depends on NIMBLE && NIMBLE_ROLE_PERIPHERAL
+       ---help---
+               Enable the NimBLE Environmental Sensing peripheral example.
+
+if EXAMPLES_NIMBLE_BLEESS
+
+config EXAMPLES_NIMBLE_BLEESS_PROGNAME
+       string "Program name"
+       default "bleess"
+       ---help---
+               This is the name of the program that will be used when the NSH 
ELF
+               program is installed.
+
+config EXAMPLES_NIMBLE_BLEESS_PRIORITY
+       int "NimBLE task priority"
+       default 100
+
+config EXAMPLES_NIMBLE_BLEESS_STACKSIZE
+       int "NimBLE stack size"
+       default DEFAULT_TASK_STACKSIZE
+
+endif # EXAMPLES_NIMBLE_BLEESS
diff --git a/examples/nimble_bleess/Make.defs b/examples/nimble_bleess/Make.defs
new file mode 100644
index 000000000..510f48140
--- /dev/null
+++ b/examples/nimble_bleess/Make.defs
@@ -0,0 +1,25 @@
+############################################################################
+# apps/examples/nimble_bleess/Make.defs
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you 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.
+#
+############################################################################
+
+ifneq ($(CONFIG_EXAMPLES_NIMBLE_BLEESS),)
+CONFIGURED_APPS += $(APPDIR)/examples/nimble_bleess
+endif
diff --git a/examples/nimble_bleess/Makefile b/examples/nimble_bleess/Makefile
new file mode 100644
index 000000000..1fb3d4edb
--- /dev/null
+++ b/examples/nimble_bleess/Makefile
@@ -0,0 +1,34 @@
+############################################################################
+# apps/examples/nimble_bleess/Makefile
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you 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.
+#
+############################################################################
+
+include $(APPDIR)/Make.defs
+
+PROGNAME  = $(CONFIG_EXAMPLES_NIMBLE_BLEESS_PROGNAME)
+PRIORITY  = $(CONFIG_EXAMPLES_NIMBLE_BLEESS_PRIORITY)
+STACKSIZE = $(CONFIG_EXAMPLES_NIMBLE_BLEESS_STACKSIZE)
+MODULE    = $(CONFIG_EXAMPLES_NIMBLE_BLEESS)
+
+CSRCS   = bleess_gap.c bleess_gatt.c
+MAINSRC = nimble_bleess_main.c
+
+include $(APPDIR)/wireless/bluetooth/nimble/Makefile.nimble
+include $(APPDIR)/Application.mk
diff --git a/examples/nimble_bleess/bleess.h b/examples/nimble_bleess/bleess.h
new file mode 100644
index 000000000..cf60a8be6
--- /dev/null
+++ b/examples/nimble_bleess/bleess.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+ * apps/examples/nimble_bleess/bleess.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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 __APPS_EXAMPLES_NIMBLE_BLEESS_BLEESS_H
+#define __APPS_EXAMPLES_NIMBLE_BLEESS_BLEESS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include "host/ble_gatt.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BLEESS_DEVICE_NAME       "NuttX NimBLE ESS"
+#define BLEESS_SERVICE_UUID      0x181a
+#define BLEESS_TEMPERATURE_UUID  0x2a6e
+#define BLEESS_HUMIDITY_UUID     0x2a6f
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+int bleess_gap_init(void);
+void bleess_gap_on_reset(int reason);
+void bleess_gap_on_sync(void);
+
+int bleess_gatt_init(void);
+void bleess_gatt_register_cb(FAR struct ble_gatt_register_ctxt *ctxt,
+                             FAR void *arg);
+void bleess_gatt_update(int16_t temperature_centi,
+                        uint16_t humidity_centi);
+
+#endif /* __APPS_EXAMPLES_NIMBLE_BLEESS_BLEESS_H */
diff --git a/examples/nimble_bleess/bleess_gap.c 
b/examples/nimble_bleess/bleess_gap.c
new file mode 100644
index 000000000..1fabe6472
--- /dev/null
+++ b/examples/nimble_bleess/bleess_gap.c
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * apps/examples/nimble_bleess/bleess_gap.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "host/ble_hs.h"
+#include "host/util/util.h"
+#include "services/gap/ble_svc_gap.h"
+
+#include "bleess.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void bleess_gap_start_advertising(void);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void bleess_gap_print_address(FAR const uint8_t *address)
+{
+  printf("%02x:%02x:%02x:%02x:%02x:%02x",
+         address[5], address[4], address[3],
+         address[2], address[1], address[0]);
+}
+
+static void
+bleess_gap_print_connection(FAR const struct ble_gap_conn_desc *desc)
+{
+  printf("handle=%u peer=", desc->conn_handle);
+  bleess_gap_print_address(desc->peer_ota_addr.val);
+  printf(" interval=%u latency=%u timeout=%u encrypted=%u bonded=%u\n",
+         desc->conn_itvl, desc->conn_latency, desc->supervision_timeout,
+         desc->sec_state.encrypted, desc->sec_state.bonded);
+}
+
+static int bleess_gap_event(FAR struct ble_gap_event *event, FAR void *arg)
+{
+  struct ble_gap_conn_desc desc;
+  int ret;
+
+  switch (event->type)
+    {
+      case BLE_GAP_EVENT_CONNECT:
+        printf("GAP connect: status=%d\n", event->connect.status);
+        if (event->connect.status == 0)
+          {
+            ret = ble_gap_conn_find(event->connect.conn_handle, &desc);
+            if (ret == 0)
+              {
+                bleess_gap_print_connection(&desc);
+              }
+          }
+        else
+          {
+            bleess_gap_start_advertising();
+          }
+
+        return 0;
+
+      case BLE_GAP_EVENT_DISCONNECT:
+        printf("GAP disconnect: reason=%d\n", event->disconnect.reason);
+        bleess_gap_start_advertising();
+        return 0;
+
+      case BLE_GAP_EVENT_CONN_UPDATE:
+        printf("GAP connection update: status=%d\n",
+               event->conn_update.status);
+        return 0;
+
+      case BLE_GAP_EVENT_ADV_COMPLETE:
+        printf("GAP advertising complete: reason=%d\n",
+               event->adv_complete.reason);
+        bleess_gap_start_advertising();
+        return 0;
+
+      case BLE_GAP_EVENT_SUBSCRIBE:
+        printf("GATT subscribe: attr=%u notify=%u indicate=%u\n",
+               event->subscribe.attr_handle,
+               event->subscribe.cur_notify,
+               event->subscribe.cur_indicate);
+        return 0;
+
+      case BLE_GAP_EVENT_MTU:
+        printf("ATT MTU: conn=%u mtu=%u\n",
+               event->mtu.conn_handle, event->mtu.value);
+        return 0;
+
+      default:
+        return 0;
+    }
+}
+
+static void bleess_gap_start_advertising(void)
+{
+  struct ble_gap_adv_params parameters;
+  struct ble_hs_adv_fields fields;
+  ble_uuid16_t service_uuid = BLE_UUID16_INIT(BLEESS_SERVICE_UUID);
+  FAR const char *name;
+  uint8_t own_address_type;
+  int ret;
+
+  ret = ble_hs_id_infer_auto(0, &own_address_type);
+  if (ret != 0)
+    {
+      printf("GAP address selection failed: %d\n", ret);
+      return;
+    }
+
+  memset(&fields, 0, sizeof(fields));
+  fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
+  fields.tx_pwr_lvl_is_present = 1;
+  fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
+
+  name = ble_svc_gap_device_name();
+  fields.name = (FAR uint8_t *)name;
+  fields.name_len = strlen(name);
+  fields.name_is_complete = 1;
+  fields.uuids16 = &service_uuid;
+  fields.num_uuids16 = 1;
+  fields.uuids16_is_complete = 1;
+
+  ret = ble_gap_adv_set_fields(&fields);
+  if (ret != 0)
+    {
+      printf("GAP advertising data failed: %d\n", ret);
+      return;
+    }
+
+  memset(&parameters, 0, sizeof(parameters));
+  parameters.conn_mode = BLE_GAP_CONN_MODE_UND;
+  parameters.disc_mode = BLE_GAP_DISC_MODE_GEN;
+
+  ret = ble_gap_adv_start(own_address_type, NULL, BLE_HS_FOREVER,
+                          &parameters, bleess_gap_event, NULL);
+  printf("GAP advertising start: ret=%d name=%s service=0x%04x\n",
+         ret, name, BLEESS_SERVICE_UUID);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int bleess_gap_init(void)
+{
+  ble_svc_gap_init();
+  return ble_svc_gap_device_name_set(BLEESS_DEVICE_NAME);
+}
+
+void bleess_gap_on_reset(int reason)
+{
+  printf("NimBLE reset: reason=%d\n", reason);
+}
+
+void bleess_gap_on_sync(void)
+{
+  int ret;
+
+  ret = ble_hs_util_ensure_addr(0);
+  if (ret != 0)
+    {
+      printf("NimBLE identity address failed: %d\n", ret);
+      return;
+    }
+
+  bleess_gap_start_advertising();
+}
diff --git a/examples/nimble_bleess/bleess_gatt.c 
b/examples/nimble_bleess/bleess_gatt.c
new file mode 100644
index 000000000..b82aae3bb
--- /dev/null
+++ b/examples/nimble_bleess/bleess_gatt.c
@@ -0,0 +1,210 @@
+/****************************************************************************
+ * apps/examples/nimble_bleess/bleess_gatt.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+
+#include "host/ble_hs.h"
+#include "host/ble_uuid.h"
+#include "services/gatt/ble_svc_gatt.h"
+
+#include "bleess.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int bleess_gatt_access(uint16_t connection_handle,
+                              uint16_t attribute_handle,
+                              FAR struct ble_gatt_access_ctxt *context,
+                              FAR void *arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const ble_uuid16_t g_bleess_service_uuid =
+  BLE_UUID16_INIT(BLEESS_SERVICE_UUID);
+static const ble_uuid16_t g_bleess_temperature_uuid =
+  BLE_UUID16_INIT(BLEESS_TEMPERATURE_UUID);
+static const ble_uuid16_t g_bleess_humidity_uuid =
+  BLE_UUID16_INIT(BLEESS_HUMIDITY_UUID);
+
+static int16_t g_bleess_temperature_centi = 2400;
+static uint16_t g_bleess_humidity_centi = 5000;
+static uint16_t g_bleess_temperature_handle;
+static uint16_t g_bleess_humidity_handle;
+
+static const struct ble_gatt_svc_def g_bleess_services[] =
+{
+  {
+    /* Service: Environmental Sensing. */
+
+    .type = BLE_GATT_SVC_TYPE_PRIMARY,
+    .uuid = &g_bleess_service_uuid.u,
+    .characteristics = (struct ble_gatt_chr_def[])
+    {
+      {
+        /* Characteristic: Temperature. */
+
+        .uuid = &g_bleess_temperature_uuid.u,
+        .access_cb = bleess_gatt_access,
+        .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY,
+      },
+
+      {
+        /* Characteristic: Humidity. */
+
+        .uuid = &g_bleess_humidity_uuid.u,
+        .access_cb = bleess_gatt_access,
+        .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY,
+      },
+
+      {
+        0, /* No more characteristics in this service. */
+      }
+    },
+  },
+
+  {
+    0, /* No more services. */
+  },
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int bleess_gatt_access(uint16_t connection_handle,
+                              uint16_t attribute_handle,
+                              FAR struct ble_gatt_access_ctxt *context,
+                              FAR void *arg)
+{
+  FAR const ble_uuid_t *uuid = context->chr->uuid;
+  uint16_t encoded_temperature;
+  uint8_t value[2];
+
+  UNUSED(connection_handle);
+  UNUSED(attribute_handle);
+  UNUSED(arg);
+
+  if (context->op != BLE_GATT_ACCESS_OP_READ_CHR)
+    {
+      return BLE_ATT_ERR_WRITE_NOT_PERMITTED;
+    }
+
+  if (ble_uuid_cmp(uuid, &g_bleess_temperature_uuid.u) == 0)
+    {
+      encoded_temperature = (uint16_t)g_bleess_temperature_centi;
+      value[0] = (uint8_t)encoded_temperature;
+      value[1] = (uint8_t)(encoded_temperature >> 8);
+    }
+  else if (ble_uuid_cmp(uuid, &g_bleess_humidity_uuid.u) == 0)
+    {
+      value[0] = (uint8_t)g_bleess_humidity_centi;
+      value[1] = (uint8_t)(g_bleess_humidity_centi >> 8);
+    }
+  else
+    {
+      return BLE_ATT_ERR_UNLIKELY;
+    }
+
+  if (os_mbuf_append(context->om, value, sizeof(value)) != 0)
+    {
+      return BLE_ATT_ERR_INSUFFICIENT_RES;
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void bleess_gatt_register_cb(FAR struct ble_gatt_register_ctxt *context,
+                             FAR void *arg)
+{
+  char uuid_string[BLE_UUID_STR_LEN];
+
+  UNUSED(arg);
+
+  if (context->op == BLE_GATT_REGISTER_OP_SVC)
+    {
+      printf("GATT service: uuid=%s handle=%u\n",
+             ble_uuid_to_str(context->svc.svc_def->uuid, uuid_string),
+             context->svc.handle);
+    }
+  else if (context->op == BLE_GATT_REGISTER_OP_CHR)
+    {
+      printf("GATT characteristic: uuid=%s value_handle=%u\n",
+             ble_uuid_to_str(context->chr.chr_def->uuid, uuid_string),
+             context->chr.val_handle);
+
+      if (ble_uuid_cmp(context->chr.chr_def->uuid,
+                       &g_bleess_temperature_uuid.u) == 0)
+        {
+          g_bleess_temperature_handle = context->chr.val_handle;
+        }
+      else if (ble_uuid_cmp(context->chr.chr_def->uuid,
+                            &g_bleess_humidity_uuid.u) == 0)
+        {
+          g_bleess_humidity_handle = context->chr.val_handle;
+        }
+    }
+}
+
+int bleess_gatt_init(void)
+{
+  int ret;
+
+  ble_svc_gatt_init();
+
+  ret = ble_gatts_count_cfg(g_bleess_services);
+  if (ret != 0)
+    {
+      return ret;
+    }
+
+  return ble_gatts_add_svcs(g_bleess_services);
+}
+
+void bleess_gatt_update(int16_t temperature_centi,
+                        uint16_t humidity_centi)
+{
+  g_bleess_temperature_centi = temperature_centi;
+  g_bleess_humidity_centi = humidity_centi;
+
+  if (g_bleess_temperature_handle != 0)
+    {
+      ble_gatts_chr_updated(g_bleess_temperature_handle);
+    }
+
+  if (g_bleess_humidity_handle != 0)
+    {
+      ble_gatts_chr_updated(g_bleess_humidity_handle);
+    }
+}
diff --git a/examples/nimble_bleess/nimble_bleess_main.c 
b/examples/nimble_bleess/nimble_bleess_main.c
new file mode 100644
index 000000000..bb04d35ff
--- /dev/null
+++ b/examples/nimble_bleess/nimble_bleess_main.c
@@ -0,0 +1,148 @@
+/****************************************************************************
+ * apps/examples/nimble_bleess/nimble_bleess_main.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "host/ble_hs.h"
+#include "host/util/util.h"
+#include "netutils/netinit.h"
+#include "nimble/nimble_port.h"
+
+#include "bleess.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BLEESS_TASK_PRIORITY CONFIG_EXAMPLES_NIMBLE_BLEESS_PRIORITY
+
+/****************************************************************************
+ * External Function Prototypes
+ ****************************************************************************/
+
+void ble_hci_sock_ack_handler(FAR void *param);
+void ble_hci_sock_set_device(int dev);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static FAR void *bleess_hci_task(FAR void *param)
+{
+  ble_hci_sock_ack_handler(param);
+  return NULL;
+}
+
+static FAR void *bleess_host_task(FAR void *param)
+{
+  nimble_port_run();
+  return NULL;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+  struct ble_npl_task host_task;
+  struct ble_npl_task hci_task;
+  int16_t temperature_centi = 2400;
+  uint16_t humidity_centi = 5000;
+  int direction = 1;
+  int ret;
+
+  if (argc > 1)
+    {
+      ble_hci_sock_set_device(atoi(argv[1]));
+    }
+
+#ifndef CONFIG_NSH_NETINIT
+  netinit_bringup();
+#endif
+
+  nimble_port_init();
+
+  ble_hs_cfg.reset_cb = bleess_gap_on_reset;
+  ble_hs_cfg.sync_cb = bleess_gap_on_sync;
+  ble_hs_cfg.gatts_register_cb = bleess_gatt_register_cb;
+  ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
+
+  ret = bleess_gap_init();
+  if (ret != 0)
+    {
+      printf("ERROR: GAP initialization failed: %d\n", ret);
+      return EXIT_FAILURE;
+    }
+
+  ret = bleess_gatt_init();
+  if (ret != 0)
+    {
+      printf("ERROR: GATT initialization failed: %d\n", ret);
+      return EXIT_FAILURE;
+    }
+
+  ret = ble_npl_task_init(&hci_task, "hci_sock", bleess_hci_task, NULL,
+                          BLEESS_TASK_PRIORITY, BLE_NPL_TIME_FOREVER,
+                          NULL, 0);
+  if (ret != 0)
+    {
+      printf("ERROR: HCI task creation failed: %d\n", ret);
+      return EXIT_FAILURE;
+    }
+
+  ret = ble_npl_task_init(&host_task, "ble_host", bleess_host_task, NULL,
+                          BLEESS_TASK_PRIORITY, BLE_NPL_TIME_FOREVER,
+                          NULL, 0);
+  if (ret != 0)
+    {
+      printf("ERROR: Host task creation failed: %d\n", ret);
+      return EXIT_FAILURE;
+    }
+
+  while (true)
+    {
+      temperature_centi += direction;
+      humidity_centi += direction * 2;
+
+      if (temperature_centi >= 2410 || temperature_centi <= 2390)
+        {
+          direction = -direction;
+        }
+
+      bleess_gatt_update(temperature_centi, humidity_centi);
+      printf("Temperature=%d.%02d C Humidity=%u.%02u %%\n",
+             temperature_centi / 100, temperature_centi % 100,
+             humidity_centi / 100, humidity_centi % 100);
+      sleep(2);
+    }
+
+  return EXIT_SUCCESS;
+}

Reply via email to