Hi All,
I am having issue building a project where I am attempting to add a custom BLE service.
The error message is shown below along with my relevant project files. Any help would be greatly appreciated!
Error message: C:/nordic/myapps/RES-BPB/src/cab_ble_service.c:218:1: error: macro "BT_GATT_CHRC_INIT" passed 18 arguments, but takes just 3
218 | );
Custom service C File:
#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include "cab_ble_service.h"
LOG_MODULE_DECLARE(CAB_BLE_SERVICE);
static bool button_state;
// static struct my_lbs_cb lbs_cb;
static struct cab_cb_s cab_cb;
static bool emergency_state;
static bool indicate_enabled;
bool emergency_cb(void)
{
return emergency_state;
}
// /* STEP 6 - Implement the write callback function of the LED characteristic */
// static ssize_t write_led(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf,
// uint16_t len, uint16_t offset, uint8_t flags)
// {
// LOG_DBG("Attribute write, handle: %u, conn: %p", attr->handle, (void *)conn);
// if (len != 1U) {
// LOG_DBG("Write led: Incorrect data length");
// return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
// }
// if (offset != 0) {
// LOG_DBG("Write led: Incorrect data offset");
// return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
// }
// if (lbs_cb.led_cb) {
// // Read the received value
// uint8_t val = *((uint8_t *)buf);
// if (val == 0x00 || val == 0x01) {
// // Call the application callback function to update the LED state
// lbs_cb.led_cb(val ? true : false);
// } else {
// LOG_DBG("Write led: Incorrect value");
// return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
// }
// }
// return len;
// }
/* STEP 6 - Implement the write callback function of the LED characteristic */
// static ssize_t write_clear_ack(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf,
// uint16_t len, uint16_t offset, uint8_t flags)
// {
// LOG_DBG("Attribute write, handle: %u, conn: %p", attr->handle, (void *)conn);
// if (len != 1U) {
// LOG_DBG("Write led: Incorrect data length");
// return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
// }
// if (offset != 0) {
// LOG_DBG("Write led: Incorrect data offset");
// return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
// }
// if (lbs_cb.led_cb) {
// // Read the received value
// uint8_t val = *((uint8_t *)buf);
// if (val == 0x00 || val == 0x01) {
// // Call the application callback function to update the LED state
// lbs_cb.led_cb(val ? true : false);
// } else {
// LOG_DBG("Write led: Incorrect value");
// return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
// }
// }
// return len;
// }
// /* STEP 5 - Implement the read callback function of the Button characteristic */
// static ssize_t read_button(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
// uint16_t len, uint16_t offset)
// {
// // get a pointer to button_state which is passed in the BT_GATT_CHARACTERISTIC() and stored in attr->user_data
// const char *value = attr->user_data;
// LOG_DBG("Attribute read, handle: %u, conn: %p", attr->handle, (void *)conn);
// if (lbs_cb.button_cb) {
// // Call the application callback function to update the get the current value of the button
// button_state = lbs_cb.button_cb();
// return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(*value));
// }
// return 0;
// }
/* STEP 5 - Implement the read callback function of the Emergency characteristic */
static ssize_t read_emergency(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
uint16_t len, uint16_t offset)
{
// get a pointer to button_state which is passed in the BT_GATT_CHARACTERISTIC() and stored in attr->user_data
const char *value = attr->user_data;
LOG_DBG("Attribute read, handle: %u, conn: %p", attr->handle, (void *)conn);
if (cab_cb.emergency_cb) {
// Call the application callback function to update the get the current value of the button
emergency_state = cab_cb.emergency_cb;
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(*value));
}
return 0;
}
/* This function is called whenever a Notification has been sent by the emergency Characteristic */
static void on_emergency_sent(struct bt_conn *conn, void *user_data)
{
ARG_UNUSED(user_data);
const bt_addr_le_t * addr = bt_conn_get_dst(conn);
printk("Data sent to Address 0x %02X %02X %02X %02X %02X %02X \n", addr->a.val[0]
, addr->a.val[1]
, addr->a.val[2]
, addr->a.val[3]
, addr->a.val[4]
, addr->a.val[5]);
}
static void cab_emergency_ccc_cfg_changed(const struct bt_gatt_attr *attr,
uint16_t value)
{
ARG_UNUSED(attr);
switch(value)
{
case BT_GATT_CCC_NOTIFY:
// Start sending stuff!
break;
case BT_GATT_CCC_INDICATE:
// Start sending stuff via indications
break;
case 0:
// Stop sending stuff
break;
default:
printk("Error, CCCD has been set to an invalid value");
}
}
/**
* @brief Characteristic and Value Declaration Macro.
*
* Helper macro to declare a characteristic attribute along with its
* attribute value.
*
* @param _uuid Characteristic attribute uuid.
* @param _props Characteristic attribute properties,
* a bitmap of ``BT_GATT_CHRC_*`` macros.
* @param _perm Characteristic Attribute access permissions,
* a bitmap of @ref bt_gatt_perm values.
* @param _read Characteristic Attribute read callback
* (@ref bt_gatt_attr_read_func_t).
* @param _write Characteristic Attribute write callback
* (@ref bt_gatt_attr_write_func_t).
* @param _user_data Characteristic Attribute user data.
*/
BT_GATT_SERVICE_DEFINE(
cab_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_CAB),
BT_GATT_CHARACTERISTIC(BT_UUID_EMERGENCY_VAL, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_READ, read_emergency, NULL, &emergency_state),
BT_GATT_CCC(cab_emergency_ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
// BT_GATT_CHARACTERISTIC(BT_UUID_CLEAR_ACK, BT_GATT_CHRC_WRITE,
// BT_GATT_PERM_WRITE, NULL, write_clear_ack, NULL),
// BT_GATT_CHARACTERISTIC(BT_UUID_EMERGENCY_REPORT, BT_GATT_CHRC_NOTIFY,
// BT_GATT_PERM_READ, read_button, NULL, &button_state),
// BT_GATT_CHARACTERISTIC(BT_UUID_HEARTBEAT_PERIOD, BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
// BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, NULL, write_led, NULL),
// BT_GATT_CHARACTERISTIC(BT_UUID_HEARTBEAT, BT_GATT_CHRC_NOTIFY,
// BT_GATT_PERM_READ, read_button, NULL, &button_state),
// BT_GATT_CHARACTERISTIC(BT_UUID_PUBLIC_KEY, BT_GATT_CHRC_READ,
// BT_GATT_PERM_READ, NULL, write_led, NULL),
// BT_GATT_CHARACTERISTIC(BT_UUID_SIGN, BT_GATT_CHRC_WRITE,
// BT_GATT_PERM_WRITE, read_button, NULL, &button_state),
// BT_GATT_CHARACTERISTIC(BT_UUID_SIGN_RESULT, BT_GATT_CHRC_NOTIFY,
// BT_GATT_PERM_NONE, NULL, write_led, NULL),
);
// /* A function to register application callbacks for the LED and Button characteristics */
// int my_lbs_init(struct my_lbs_cb *callbacks)
// {
// if (callbacks) {
// lbs_cb.led_cb = callbacks->led_cb;
// lbs_cb.button_cb = callbacks->button_cb;
// }
// return 0;
// }
/* A function to register application callbacks for the LED and Button characteristics */
int Cab_Init(void)
{
cab_cb.emergency_cb = &emergency_cb;
return 0;
}
/* STEP 5.1 - Define the function to send indications */
void Cab_Send_Emergency_Notification(struct bt_conn *conn)
{
/*
The attribute for the TX characteristic is used with bt_gatt_is_subscribed
to check whether notification has been enabled by the peer or not.
Attribute table: 0 = Service, 1 = Primary service, 2 = RX, 3 = TX, 4 = CCC.
*/
const struct bt_gatt_attr *attr = &cab_svc.attrs[2];
struct bt_gatt_notify_params params =
{
.uuid = BT_UUID_EMERGENCY,
.attr = attr,
.data = &emergency_state,
.len = sizeof(emergency_state),
.func = on_emergency_sent
};
// Check whether notifications are enabled or not
if(bt_gatt_is_subscribed(conn, attr, BT_GATT_CCC_NOTIFY))
{
// Send the notification
int err = bt_gatt_notify_cb(conn, ¶ms);
if(err){
printk("Error, unable to send notification. Error %d\n", err);
}
}
else
{
printk("Warning, notification not enabled on the selected attribute\n");
}
}
ble service header file:
#ifndef CAB_BLE_SERVICE_H_
#define CAB_BLE_SERVICE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <zephyr/types.h>
#define BT_UUID_CAB_VAL \
BT_UUID_128_ENCODE(0x4d2e0000, 0x3edd, 0x4a55, 0xa57a, 0x248a3c37382c)
/** @brief Emergency Characteristic UUID. */
#define BT_UUID_EMERGENCY_VAL \
BT_UUID_128_ENCODE(0x4d2e0002, 0x3edd, 0x4a55, 0xa57a, 0x248a3c37382c)
/** @brief Clear/Ack Emergency Characteristic UUID. */
#define BT_UUID_CLEAR_ACK_VAL \
BT_UUID_128_ENCODE(0x4d2e0003, 0x3edd, 0x4a55, 0xa57a, 0x248a3c37382c)
/** @brief Emergency Report Characteristic UUID. */
#define BT_UUID_EMERGENCY_REPORT_VAL \
BT_UUID_128_ENCODE(0x4d2e0004, 0x3edd, 0x4a55, 0xa57a, 0x248a3c37382c)
/** @brief Heartbeat Period Characteristic UUID. */
#define BT_UUID_HEARTBEAT_PERIOD_VAL \
BT_UUID_128_ENCODE(0x4d2e0005, 0x3edd, 0x4a55, 0xa57a, 0x248a3c37382c)
/** @brief Heartbeat Characteristic UUID. */
#define BT_UUID_HEARTBEAT_VAL \
BT_UUID_128_ENCODE(0x4d2e0006, 0x3edd, 0x4a55, 0xa57a, 0x248a3c37382c)
/** @brief Public Key Characteristic UUID. */
#define BT_UUID_PUBLIC_KEY_VAL \
BT_UUID_128_ENCODE(0x4d2e0007, 0x3edd, 0x4a55, 0xa57a, 0x248a3c37382c)
/** @brief Sign Characteristic UUID. */
#define BT_UUID_SIGN_VAL \
BT_UUID_128_ENCODE(0x4d2e0008, 0x3edd, 0x4a55, 0xa57a, 0x248a3c37382c)
/** @brief Sign Result Characteristic UUID. */
#define BT_UUID_SIGN_RESULT_VAL \
BT_UUID_128_ENCODE(0x4d2e0009, 0x3edd, 0x4a55, 0xa57a, 0x248a3c37382c)
#define BT_UUID_CAB BT_UUID_DECLARE_128(BT_UUID_CAB_VAL)
#define BT_UUID_EMERGENCY BT_UUID_DECLARE_128(BT_UUID_EMERGENCY_VAL)
#define BT_UUID_CLEAR_ACK BT_UUID_DECLARE_128(BT_UUID_CLEAR_ACK_VAL)
#define BT_UUID_EMERGENCY_REPORT BT_UUID_DECLARE_128(BT_UUID_EMERGENCY_REPORT_VAL)
#define BT_UUID_HEARTBEAT_PERIOD BT_UUID_DECLARE_128(BT_UUID_HEARTBEAT_PERIOD_VAL)
#define BT_UUID_HEARTBEAT BT_UUID_DECLARE_128(BT_UUID_HEARTBEAT_VAL)
#define BT_UUID_PUBLIC_KEY BT_UUID_DECLARE_128(BT_UUID_PUBLIC_KEY_VAL)
#define BT_UUID_SIGN BT_UUID_DECLARE_128(BT_UUID_SIGN_VAL)
#define BT_UUID_SIGN_RESULT BT_UUID_DECLARE_128(BT_UUID_SIGN_RESULT_VAL)
typedef bool (*emergency_cb_t)(void);
/** @brief Callback struct used by the LBS Service. */
struct cab_cb_s {
/** LED state change callback. */
emergency_cb_t emergency_cb;
};
int Cab_Init(void);
void Cab_Send_Emergency_Notification(struct bt_conn *conn);
#ifdef __cplusplus
}
#endif
#endif /* CAB_BLE_SERVICE_H_ */
prj.conf
# # Copyright (c) 2018 Nordic Semiconductor # # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # CONFIG_NCS_SAMPLES_DEFAULTS=y CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_DEVICE_NAME="AnyXXXX" # Enable the LBS service CONFIG_BT_LBS=y CONFIG_BT_LBS_POLL_BUTTON=y CONFIG_DK_LIBRARY=y # Enable Device Information Service (DIS) CONFIG_BT_DIS=y CONFIG_BT_DIS_MANUF="RTL" CONFIG_BT_DIS_MODEL="CAB" CONFIG_BT_DIS_HW_REV=y CONFIG_BT_DIS_HW_REV_STR="1.0.1" CONFIG_BT_DIS_SW_REV=y CONFIG_BT_DIS_SW_REV_STR="Bootloader: 1.0.1, SoftDevice: 6.1.0, Application: 2.0.12" # Enable Battery Service (BAS) CONFIG_BT_BAS=y CONFIG_BT_BAS_LOG_LEVEL_DBG=y # Enable ADC for battery measurement CONFIG_ADC=y # Increase stack size for the main thread and System Workqueue CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 CONFIG_MAIN_STACK_SIZE=2048 # Enable PWM CONFIG_LED=y CONFIG_PWM=y CONFIG_LED_PWM=y CONFIG_TIMER=y CONFIG_PWM_LOG_LEVEL_DBG=y