Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added demo for BLE #2801

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions examples/ble/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# ##############################################################################
# apps/examples/ble/CMakeLists.txt
#
# 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_BLE)
nuttx_add_application(
NAME
${CONFIG_EXAMPLES_BLE_PROGNAME}
PRIORITY
${CONFIG_EXAMPLES_BLE_PRIORITY}
STACKSIZE
${CONFIG_EXAMPLES_BLE_STACKSIZE}
MODULE
${CONFIG_EXAMPLES_BLE}
SRCS
ble_main.c)
endif()
37 changes: 37 additions & 0 deletions examples/ble/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#

config EXAMPLES_BLE
tristate "BLE sensor reading example"
default n
depends on WIRELESS_BLUETOOTH
---help---
Enable the BLE example

if EXAMPLES_BLE

config EXAMPLES_BLE_PROGNAME
string "Program name"
default "ble"
---help---
This is the name of the program that will be used when the NSH ELF
program is installed.

config EXAMPLES_BLE_PRIORITY
int "BLE task priority"
default 100

config EXAMPLES_BLE_STACKSIZE
int "BLE stack size"
default DEFAULT_TASK_STACKSIZE

config EXAMPLES_BLE_USE_BME680
bool "Use BME680 sensor data"
default n
depends on SENSORS_BME680
---help---
If enabled, use real BME680 sensor data. If disabled, use dummy data.

endif
23 changes: 23 additions & 0 deletions examples/ble/Make.defs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
############################################################################
# apps/examples/ble/Make.defs
#
# 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_BLE),)
CONFIGURED_APPS += $(APPDIR)/examples/ble
endif
39 changes: 39 additions & 0 deletions examples/ble/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
############################################################################
# apps/examples/ble/Makefile
#
# 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

# BLE Barometer sensor example built-in application info

PROGNAME = $(CONFIG_EXAMPLES_BLE_PROGNAME)
PRIORITY = $(CONFIG_EXAMPLES_BLE_PRIORITY)
STACKSIZE = $(CONFIG_EXAMPLES_BLE_STACKSIZE)
MODULE = $(CONFIG_EXAMPLES_BLE)

CSRCS = ble.c
MAINSRC = ble_main.c

ifeq ($(CONFIG_EXAMPLES_BLE_USE_BME680),y)
CSRCS += sensors.c
else
CSRCS += dummy.c
endif

include $(APPDIR)/Application.mk
198 changes: 198 additions & 0 deletions examples/ble/ble.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
#include <nuttx/wireless/bluetooth/bt_core.h>

Check failure on line 1 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

Missing file header comment block

Check warning on line 1 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

#include outside of 'Included Files' section
#include <nuttx/wireless/bluetooth/bt_gatt.h>

Check failure on line 2 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

Path relative to repository other than "nuttx" must begin with the root directory

Check warning on line 2 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

#include outside of 'Included Files' section
#include <nuttx/wireless/bluetooth/bt_ioctl.h>

Check warning on line 3 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

#include outside of 'Included Files' section
#include <netpacket/bluetooth.h>

Check warning on line 4 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

#include outside of 'Included Files' section
#include "sensors.h"

Check warning on line 5 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

#include outside of 'Included Files' section

#define GASVC 0x0001

Check warning on line 7 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

#define outside of 'Pre-processor Definitions' section
#define NAME_CHR (GASVC + 0x0002)

Check warning on line 8 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

#define outside of 'Pre-processor Definitions' section
#define NAME_DSC (GASVC + 0x0003)

Check warning on line 9 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

#define outside of 'Pre-processor Definitions' section
#define APPEARANCE_CHR (GASVC + 0x0004)

Check warning on line 10 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

#define outside of 'Pre-processor Definitions' section
#define APPEARANCE_DSC (GASVC + 0x0005)

Check warning on line 11 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

#define outside of 'Pre-processor Definitions' section
#define SENSOR_SVC (APPEARANCE_DSC + 0x0001)
#define TEMP_CHR (SENSOR_SVC + 0x0001)
#define TEMP_DSC (SENSOR_SVC + 0x0002)
#define HUM_CHR (TEMP_DSC + 0x0001)
#define HUM_DSC (TEMP_DSC + 0x0002)
#define GAS_CHR (HUM_DSC + 0x0001)
#define GAS_DSC (HUM_DSC + 0x0002)
#define PRESS_CHR (GAS_DSC + 0x0001)
#define PRESS_DSC (GAS_DSC + 0x0002)

// Bluetooth UUIDs

Check failure on line 22 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

C++ style comment

Check failure on line 22 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

Mixed case identifier found

Check failure on line 22 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

Mixed case identifier found
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_uuid_s g_appearance_uuid =
{
.type = BT_UUID_16,
.u.u16 = BT_UUID_GAP_APPEARANCE,
};

static struct bt_uuid_s g_sensor_uuid = {

Check failure on line 41 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

Left bracket not on separate line
.type = BT_UUID_128,
.u.u128 = {

Check failure on line 43 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

Left bracket not on separate line

Check failure on line 43 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

Dangling whitespace at the end of line
0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0,

Check failure on line 44 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

Upper case hex constant found

Check failure on line 44 in examples/ble/ble.c

View workflow job for this annotation

GitHub Actions / check

Upper case hex constant found
0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0
}
};

static struct bt_uuid_s g_temp_uuid =
{
.type = BT_UUID_16,
.u.u16 = 0x2A6E, // Temperature UUID
};

static struct bt_uuid_s g_hum_uuid =
{
.type = BT_UUID_16,
.u.u16 = 0x2A6F, // Humidity UUID
};

static struct bt_uuid_s g_press_uuid =
{
.type = BT_UUID_16,
.u.u16 = 0x2A6D, // Pressure UUID
};

// GATT characteristics
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_gatt_chrc_s g_appearance_chrc =
{
.properties = BT_GATT_CHRC_READ,
.value_handle = APPEARANCE_DSC,
.uuid = &g_appearance_uuid,
};

static struct bt_gatt_chrc_s g_temp_chrc =
{
.properties = BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
.value_handle = TEMP_DSC,
.uuid = &g_temp_uuid,
};

static struct bt_gatt_chrc_s g_hum_chrc =
{
.properties = BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
.value_handle = HUM_DSC,
.uuid = &g_hum_uuid,
};

static struct bt_gatt_chrc_s g_press_chrc =
{
.properties = BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
.value_handle = PRESS_DSC,
.uuid = &g_press_uuid,
};

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)
{
const char *name = CONFIG_DEVICE_NAME;
return bt_gatt_attr_read(conn, attr, buf, len, offset, name, strlen(name));
}

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 = 0; // Set appropriate appearance value
return bt_gatt_attr_read(conn, attr, buf, len, offset, &appearance, sizeof(appearance));
}

static int read_temperature(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 temp = (uint16_t) (get_temperature() * 100);
return bt_gatt_attr_read(conn, attr, buf, len, offset, &temp, sizeof(uint16_t));
}

static int read_humidity(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 hum = (uint16_t) (get_humidity() * 100);
return bt_gatt_attr_read(conn, attr, buf, len, offset, &hum, sizeof(uint16_t));
}

static int read_gas(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 gas = (uint16_t) (get_gas_resistance() * 100);
return bt_gatt_attr_read(conn, attr, buf, len, offset, &gas, sizeof(uint16_t));
}

static int read_pressure(FAR struct bt_conn_s *conn,
FAR const struct bt_gatt_attr_s *attr,
FAR void *buf, uint8_t len, uint16_t offset)
{
uint32_t press = (uint32_t) (get_pressure() * 1000);
return bt_gatt_attr_read(conn, attr, buf, len, offset, &press, sizeof(uint32_t));
}

// GATT attributes
static const struct bt_gatt_attr_s 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, NULL),
BT_GATT_CHARACTERISTIC(APPEARANCE_CHR, &g_appearance_chrc),
BT_GATT_DESCRIPTOR(APPEARANCE_DSC, &g_appearance_uuid,
BT_GATT_PERM_READ, read_appearance, NULL, NULL),

BT_GATT_PRIMARY_SERVICE(SENSOR_SVC, &g_sensor_uuid),
BT_GATT_CHARACTERISTIC(TEMP_CHR, &g_temp_chrc),
BT_GATT_DESCRIPTOR(TEMP_DSC, &g_temp_uuid, BT_GATT_PERM_READ, read_temperature, NULL, NULL),
BT_GATT_CHARACTERISTIC(HUM_CHR, &g_hum_chrc),
BT_GATT_DESCRIPTOR(HUM_DSC, &g_hum_uuid, BT_GATT_PERM_READ, read_humidity, NULL, NULL),
BT_GATT_CHARACTERISTIC(PRESS_CHR, &g_press_chrc),
BT_GATT_DESCRIPTOR(PRESS_DSC, &g_press_uuid, BT_GATT_PERM_READ, read_pressure, NULL, NULL),
};

static void start_scanning(void) {
struct btreq_s btreq;
memset(&btreq, 0, sizeof(struct btreq_s));
strlcpy(btreq.btr_name, "bnep0", 16);
btreq.btr_dupenable = false;

int sockfd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP);
if (sockfd < 0)
{
fprintf(stderr, "ERROR: failed to create socket");
return;
}
int ret = ioctl(sockfd, SIOCBTSCANSTART,
(unsigned long)((uintptr_t)&btreq));
if (ret < 0)
{
fprintf(stderr, "ERROR: ioctl(SIOCBTSCANSTART) failed");
}
close(sockfd);
}

void setup_ble(void) {
// TODO: Scanning is enabled here in order to make advertising work.
// It has been noticed that advertising packets are not sent by default,
// unless scanning is enabled.
start_scanning();
bt_gatt_register(attrs, nitems(attrs));
}
59 changes: 59 additions & 0 deletions examples/ble/ble_main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/****************************************************************************
* apps/examples/ble/ble_main.c
*
* 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 <pthread.h>
#include "sensors.h"

extern void setup_ble(void);

#define STACKSIZE 2048

int main(int argc, FAR char *argv[]) {
int ret;

init_sensors();
setup_ble();

pthread_t thread;
pthread_attr_t attr;
struct sched_param param;

pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, STACKSIZE);
param.sched_priority = SCHED_PRIORITY_DEFAULT;
pthread_attr_setschedparam(&attr, &param);

ret = pthread_create(&thread, &attr, monitor_sensors, NULL);
if (ret != 0) {
printf("Error: pthread_create failed: %d\n", ret);
return 1;
}

pthread_join(thread, NULL);

close_sensors_fd();

return 0;
}
Loading
Loading