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