Cmake error

Hi!

I have been developing a GATTClient and GATTServer on two separate nrf52840dk boards and have been doing so for a long time.

This Friday I got everything to work when it comes to notifications and write without response. Offline I tried adding functionality for extending the data length and setting the PHY to 2 on the server. Once I tried to build this code and flash it to my Server the whole functionality just crashed.

It went from looking like this (GATTClient --> GATTServer) on the left and GATTServer output on the right:
 

To now the dev-kits are connecting but the Client does not discover the service I have built on the Server side which it has done flawlessly so far.

I THINK I have narrowed it down to some sort of Cmake issue on the Client side for some reason, and I get the following error messages in my output console of the NRF Connect for VSCode:



I have tried:

- Restarting VSCode and my computer several times.

- Updating every extension I have and also VSCode

- Re-installed the nRF Connect extension pack for VSCode

- Re-installed the SDK Toolchain to get a newer version, from 2.7.0 to 2.9.1 

And still this issue is there, please help me how to proceed?

Regards,
Björn

PS: Just for reference, I attach the Client code below:

/*
 * Copyright (c) 2020 SixOctets Systems
 *
 * SPDX-License-Identifier: Apache-2.0
 */

 #include <stdio.h>
 #include <stddef.h>
 #include <errno.h>
 
 #include <zephyr/kernel.h>
 #include <zephyr/sys/printk.h>
 #include <zephyr/sys/byteorder.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>
 
 /* --------------------- START OF FROG UUID:s ---------------- */
 
 #define FROG_SERVICE BT_UUID_128_ENCODE(0xd099cd20, 0xb2ea, 0x11e5, 0xbf01, 0x0002a5d5c51b)
 // Notify characteristics
 #define FROG_TXDATA_UUID BT_UUID_128_ENCODE(0x388706a0, 0xb2eb, 0x11e5, 0xa790, 0x0002a5d5c51b)
 #define FROG_RXCREDIT BT_UUID_128_ENCODE(0x43802b40, 0xb2eb, 0x11e5, 0xb6c5, 0x0002a5d5c51b)
 
 // Write without response characteristics
 #define FROG_TXCREDIT_UUID BT_UUID_128_ENCODE(0x2c1b1820, 0xb2eb, 0x11e5, 0x8f66, 0x0002a5d5c51b)
 #define FROG_RXDATA BT_UUID_128_ENCODE(0x2016ec20, 0xb2eb, 0x11e5, 0xa307, 0x0002a5d5c51b)
 
 // Macros for service and characteristics
 
 #define BT_UUID_FROG BT_UUID_DECLARE_128(FROG_SERVICE)
 #define BT_UUID_TXDATA BT_UUID_DECLARE_128(FROG_TXDATA_UUID)
 #define BT_UUID_RXCREDIT BT_UUID_DECLARE_128(FROG_RXCREDIT)
 
 #define BT_UUID_TXCREDIT BT_UUID_DECLARE_128(FROG_TXCREDIT_UUID)
 #define BT_UUID_RXDATA BT_UUID_DECLARE_128(FROG_RXDATA)
 
 /* ----------------------------- END ------------------------- */
 
 #define STACKSIZE 1024
 #define PRIORITY 7
 static uint16_t txcredit_wor_data = 2U;
 
 
 static int scan_start(void);
 
 static struct bt_conn *default_conn;
 /* Variable for write without response*/
 static uint16_t char_handle = 0;
 
 static struct bt_uuid_16 frog_ccc_discover_uuid = BT_UUID_INIT_16(0);
 static struct bt_uuid_128 frog_discover_uuid = BT_UUID_INIT_128(0);
 //static const struct bt_uuid *ccc_uuid = BT_UUID_GATT_CCC;
 //static const struct bt_uuid *ccc_uuid2 = BT_UUID_GATT_CCC;
 //static const struct bt_uuid *ccc_uuid2;
 static struct bt_gatt_discover_params discover_params;
 static struct bt_gatt_subscribe_params subscribe_params_txdata;
 static struct bt_gatt_subscribe_params subscribe_params_rxcredit;
 
 static uint8_t notify_func(struct bt_conn *conn,
				struct bt_gatt_subscribe_params *params,
				const void *data, uint16_t length)
 {
 
	 if (!data) {
		 printk("[UNSUBSCRIBED]\n");
		 params->value_handle = 0U;
		 return BT_GATT_ITER_STOP;
	 }
 
 
	 printf("[NOTIFICATION]: Data from server %p.\n", data);
	 uint8_t* uint8data = (uint8_t *)data;
	 printf("[NOTIFICATION]: Data from server");
	 int i;
	 for (i = 0; i < length; ++i)
	 {
		 printf(" 0x%02x", uint8data[i]);
	 }
	 printf("\n");	
 
	 return BT_GATT_ITER_CONTINUE;
 }
 
 static uint8_t discover_func(struct bt_conn *conn,
				  const struct bt_gatt_attr *attr,
				  struct bt_gatt_discover_params *params)
 {
	 int err;
 
	 if (!attr) {
		 printk("Discover complete\n");
		 (void)memset(params, 0, sizeof(*params));
		 return BT_GATT_ITER_STOP;
	 }
 
	 printk("[ATTRIBUTE] handle %u\n", attr->handle);
 
	 if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_FROG)) {
		 printk("Discovering TxData\n");
 
		 //What attribute in the table are we looking for
		 //Copy that UUID information into the &frog_discover_uuid address
		 //Put the information into the discover parameters and call the bt_gatt_discover to find that characteristic
		 //BUT search in the next start_handle, otherwise we are looking in the same place. 
		 memcpy(&frog_discover_uuid, BT_UUID_TXDATA, sizeof(frog_discover_uuid));
		 discover_params.uuid = &frog_discover_uuid.uuid;
		 discover_params.start_handle = attr->handle + 1;
		 discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
 
		 err = bt_gatt_discover(conn, &discover_params);
		 if (err) {
			 printk("Discover failed (err %d)\n", err);
		 }
 
	 //	
	 } else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_TXDATA)) {
 
		 printk("Discovering CCCD TxData\n");
	 
		 memcpy(&frog_ccc_discover_uuid, BT_UUID_GATT_CCC, sizeof(frog_ccc_discover_uuid));
		 discover_params.uuid = &frog_ccc_discover_uuid.uuid;
		 discover_params.start_handle = bt_gatt_attr_value_handle(attr);//attr->handle + 1;
		 discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
 
		 subscribe_params_txdata.value_handle = bt_gatt_attr_value_handle(attr);
 
		 err = bt_gatt_discover(conn, &discover_params);
		 if (err) {
			 printk("Discover failed (err %d)\n", err);
		 }
	 } else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_RXCREDIT)) {
		 
		 printk("[CHARACTERISTIC] RxCredit handle %u\n", attr->handle);
		 printk("Discovering CCC RxCredit\n");
		 //memcpy(&frog_discover_uuid, BT_UUID_GATT_CCC, sizeof(frog_discover_uuid));
 
		 memcpy(&frog_ccc_discover_uuid, BT_UUID_GATT_CCC, sizeof(frog_ccc_discover_uuid));
		 discover_params.uuid = &frog_ccc_discover_uuid.uuid;
		 discover_params.start_handle = bt_gatt_attr_value_handle(attr);
		 discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
 
		 printk("Value handle RxCredit: %d \n", bt_gatt_attr_value_handle(attr));
 
		 subscribe_params_rxcredit.value_handle = bt_gatt_attr_value_handle(attr);
 
		 err = bt_gatt_discover(conn, &discover_params);
		 if (err) {
			 printk("Discover failed (err %d)\n", err);
		 }
	 } else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_GATT_CCC)){
		 //printk("Discover params Start handle:%d\n", discover_params.start_handle);
		 //printk("Discover params Value handle: TxData %d\n", subscribe_params_txdata.value_handle);
 
		 printk("Discovered CCCD \n");
 
		 if (attr->handle-1 == subscribe_params_txdata.value_handle)
		 {
			 printk("[SUBSCRIBE PARAMS] TxData\n");
			 subscribe_params_txdata.notify = notify_func;
			 subscribe_params_txdata.value = BT_GATT_CCC_NOTIFY;
			 subscribe_params_txdata.ccc_handle = attr->handle;
	 
			 err = bt_gatt_subscribe(conn, &subscribe_params_txdata);
			 if (err && err != -EALREADY) {
				 printk("Subscribe failed (err %d)\n", err);
			 } else {
				 printk("[SUBSCRIBED] TxData \n");
			 }
 
			 printk("Discovering RxCredit\n");
			 //memcpy(&frog_discover_uuid, BT_UUID_GATT_CCC, sizeof(frog_discover_uuid));
			 memcpy(&frog_discover_uuid, BT_UUID_RXCREDIT, sizeof(frog_discover_uuid));
			 discover_params.uuid = &frog_discover_uuid.uuid;
			 discover_params.start_handle = attr->handle + 1;
			 discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;	
		 } 
 
		 else if (attr->handle-1 == subscribe_params_rxcredit.value_handle)
		 {
			 printk("[SUBSCRIBE PARAMS] RxCredit\n");
			 subscribe_params_rxcredit.notify = notify_func;
			 subscribe_params_rxcredit.value = BT_GATT_CCC_NOTIFY;
			 subscribe_params_rxcredit.ccc_handle = attr->handle;
	 
			 err = bt_gatt_subscribe(conn, &subscribe_params_rxcredit);
			 if (err && err != -EALREADY) {
				 printk("Subscribe failed (err %d)\n", err);
			 } else {
				 printk("[SUBSCRIBED] RxCredit\n");
			 }
			 
			 printk("Discovering TxCredit\n");
			 memcpy(&frog_discover_uuid, BT_UUID_TXCREDIT, sizeof(frog_discover_uuid));
			 discover_params.uuid = &frog_discover_uuid.uuid;
			 discover_params.start_handle = attr->handle + 1;
			 discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;	
 
			 
			 
		 } 
		 
		 //subscribe_params_rxcredit.value_handle = bt_gatt_attr_value_handle(attr); 
		 
 
		 err = bt_gatt_discover(conn, &discover_params);
		 if (err) {
			 printk("Discover failed (err %d)\n", err);
		 }
		 
	 } else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_TXCREDIT)) {
 
		 // Saving TxCredit handle in char_handle for write without response
		 char_handle = bt_gatt_attr_value_handle(attr);
 
		 printk("Discovering RxData \n");
		 memcpy(&frog_discover_uuid, BT_UUID_RXDATA, sizeof(frog_discover_uuid));
		 discover_params.uuid = &frog_discover_uuid.uuid;
		 discover_params.start_handle = attr->handle + 1;
		 discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
 
		 err = bt_gatt_discover(conn, &discover_params);
		 if (err) {
			 printk("Discover failed (err %d)\n", err);
		 }
 
 
		 return BT_GATT_ITER_STOP;
	 }
 
	 return BT_GATT_ITER_STOP;
 }
 
 static void connected(struct bt_conn *conn, uint8_t conn_err)
 {
	 char addr[BT_ADDR_LE_STR_LEN];
	 int err;
 
	 bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
 
	 if (conn_err) {
		 printk("Failed to connect to %s (%u)\n", addr, conn_err);
 
		 bt_conn_unref(default_conn);
		 default_conn = NULL;
 
		 scan_start();
		 return;
	 }
 
	 printk("Connected: %s\n", addr);
 
	 if (conn == default_conn) {
		 memcpy(&frog_discover_uuid, BT_UUID_FROG, sizeof(frog_discover_uuid));
		 discover_params.uuid = &frog_discover_uuid.uuid;
		 discover_params.func = discover_func;
		 discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
		 discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
		 discover_params.type = BT_GATT_DISCOVER_PRIMARY;
 
		 err = bt_gatt_discover(default_conn, &discover_params);
		 if (err) {
			 printk("Discover failed(err %d)\n", err);
			 return;
		 }
	 }
 }
 
 static bool eir_found(struct bt_data *data, void *user_data)
 {
	 bt_addr_le_t *addr = user_data;
	 int i;
 
	 printk("[AD]: %u data_len %u\n", data->type, data->data_len);
	 switch (data->type) {
	 case BT_DATA_UUID128_SOME:
	 case BT_DATA_UUID128_ALL:
		 if (data->data_len % BT_UUID_SIZE_128 != 0U) {
			 printk("AD malformed\n");
			 return true;
		 }
		 
		 printk("INSIDE SWITCH\n");
 
		 for (i = 0; i < data->data_len; i += BT_UUID_SIZE_128) {
			 struct bt_uuid *uuid128;
			 uint8_t btadvData[16];
			 memcpy(btadvData, data->data, 16);
			 uuid128 = (struct bt_uuid *)btadvData;
			 int err;
			 printk("INSIDE FOR LOOP\n");
 
 
			 if (bt_uuid_cmp(uuid128, BT_UUID_TXDATA)) {
				 //printk("COMPARISON OK!\n");
				 printk("uuid128 == TXDATA\n");				
					 err = bt_le_scan_stop();
					 if(err) {
						 printk("Stop LE scan failed (err %d)\n", err);					
					 }
				 printk("make connection\n");
 
				 err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
						 BT_LE_CONN_PARAM_DEFAULT,
						 &default_conn);
 
				 printk("err: %d\n", err);
 
				 if (err) {
					 printk("Create connection failed (err %d)\n",
						 err);
				 }
				 //continue;
				 return false;
			 } if (bt_uuid_cmp(uuid128, BT_UUID_RXCREDIT)) {
				 //printk("COMPARISON OK!\n");
				 printk("uuid128 == RXCREDIT\n");				
					 err = bt_le_scan_stop();
					 if(err) {
						 printk("Stop LE scan failed (err %d)\n", err);					
					 }
				 printk("make connection");
 
				 err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
						 BT_LE_CONN_PARAM_DEFAULT,
						 &default_conn);
 
				 printk("err: %d\n", err);
 
				 if (err) {
					 printk("Create connection failed (err %d)\n",
						 err);
				 }
				 //continue;
				 return false;				
			 }
		 }
	 }
	 return true;
 }
 
 static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
			  struct net_buf_simple *ad)
 {
	 char dev[BT_ADDR_LE_STR_LEN];
 
	 bt_addr_le_to_str(addr, dev, sizeof(dev));
	 printk("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i\n",
			dev, type, ad->len, rssi);
 
	 /* We're only interested in connectable events */
	 if (type == BT_HCI_ADV_IND || type == BT_HCI_ADV_DIRECT_IND) {
		 bt_data_parse(ad, eir_found, (void *)addr);
	 }
 }
 
 static int scan_start(void)
 {
	 /* Use active scanning and disable duplicate filtering to handle any
	  * devices that might update their advertising data at runtime.
	  */
	 struct bt_le_scan_param scan_param = {
		 .type       = BT_LE_SCAN_TYPE_ACTIVE,
		 .options    = BT_LE_SCAN_OPT_NONE,
		 .interval   = BT_GAP_SCAN_FAST_INTERVAL,
		 .window     = BT_GAP_SCAN_FAST_WINDOW,
	 };
 
	 return bt_le_scan_start(&scan_param, device_found);
 }
 
 static void disconnected(struct bt_conn *conn, uint8_t reason)
 {
	 char addr[BT_ADDR_LE_STR_LEN];
	 int err;
 
	 bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
 
	 printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);
 
	 if (default_conn != conn) {
		 return;
	 }
 
	 bt_conn_unref(default_conn);
	 default_conn = NULL;
 
	 err = scan_start();
	 if (err) {
		 printk("Scanning failed to start (err %d)\n", err);
	 }
 }
 
 BT_CONN_CB_DEFINE(conn_callbacks) = {
	 .connected = connected,
	 .disconnected = disconnected,
 };
 
 int frog_txcredit_wor(uint16_t txcredit_val) {
	 return bt_gatt_write_without_response(default_conn, char_handle, &txcredit_val, sizeof(txcredit_val), false);
 }
 
 
 static void simulate_data(void)
 {
	 txcredit_wor_data++;
	 if (txcredit_wor_data == 200) {
		 txcredit_wor_data = 2;
	 }
 
 }
 
 /* Function to send data using Write Without Response */
 void write_without_resp_data_thread(void) { //uint16_t *data, uint16_t len
 
	 printk("[CHAR] WWOR Handle: %u\n", char_handle);
 
 
 
	 printk("DO WE EVEN GET HERE?!?!\n");
 
	 while (1) {
 
		 if (!default_conn || !char_handle) {
			 printk("No connection or characteristic handle found!\n");
			 //return;
		 }
 
		 printk("[CHAR] WWOR Handle: %u\n", char_handle);
 
		 simulate_data();
 
		 int err = frog_txcredit_wor(txcredit_wor_data);
 
		 if (err) {
			 printk("Write Without Response failed (err %d)\n", err);
		 } else {
			 printk("Write Without Response sent: %u\n", txcredit_wor_data); //len,
		 }
		 k_sleep(K_MSEC(500));
 
	 }
 
 }
 
 
 
 
 int main(void)
 {
	 int err;
 
	 err = bt_enable(NULL);
	 if (err) {
		 printk("Bluetooth init failed (err %d)\n", err);
		 return 0;
	 }
 
	 printk("Bluetooth initialized\n");
 
	 err = scan_start();
 
	 if (err) {
		 printk("Scanning failed to start (err %d)\n", err);
		 return 0;
	 }
 
	 printk("Scanning successfully started\n");
 
	 /* Wait for connection */
	 while (!default_conn) {
		 k_sleep(K_MSEC(100));
	 }
 
 
	 return 0;
 }
 K_THREAD_DEFINE(write_without_resp_thread, STACKSIZE, write_without_resp_data_thread, NULL, NULL,
	 NULL, PRIORITY, 0, 0);

Parents
  • Hi

    Okay, thank you for the additional info. From the latest screenshot it looks like you're trying to use the NCS v2.9.1 but that the activated toolchain is v2.6.1, which will likely cause these "outdated" messages.

    In the VS Code extension, when building your project, please make sure the SDK and toolchain versions match before pressing the build button. I attached a screenshot from a sample environment on my end. You can open a dropdown menu to choose the toolchain in the "Add Build Configuration" window.

    Best regards,

    Simon

Reply
  • Hi

    Okay, thank you for the additional info. From the latest screenshot it looks like you're trying to use the NCS v2.9.1 but that the activated toolchain is v2.6.1, which will likely cause these "outdated" messages.

    In the VS Code extension, when building your project, please make sure the SDK and toolchain versions match before pressing the build button. I attached a screenshot from a sample environment on my end. You can open a dropdown menu to choose the toolchain in the "Add Build Configuration" window.

    Best regards,

    Simon

Children
Related