<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Custom service GATTServer and GATTClient</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/113830/custom-service-gattserver-and-gattclient</link><description>Hello experts! I have been trying for some time now setting up my own custom service GATTServer and GATTClient with two nrf52840 DK. 
 
 On the server-side I have modified the BLE peripheral sample project and it works as it should when I try it with</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 20 Aug 2024 09:00:47 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/113830/custom-service-gattserver-and-gattclient" /><item><title>RE: Custom service GATTServer and GATTClient</title><link>https://devzone.nordicsemi.com/thread/498988?ContentTypeID=1</link><pubDate>Tue, 20 Aug 2024 09:00:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c581552a-7633-4daf-ba93-a70fd3d04e19</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;Hi Bjorn,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Please try to debug. If you see it&amp;#39;s disconnected there must be a disconnected reason. You can use the sniffer trace to debug more.&amp;nbsp;&lt;br /&gt;Please make sure that you have gone through the NCS fundamental course and the BLE fundamental course in our Academy.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;My suggestion is to start with the peripheral_nus and the central_nus. If you test with the unmodified samples do they work ?&amp;nbsp;&lt;br /&gt;I don&amp;#39;t see much different between your application and the nus samples.&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Custom service GATTServer and GATTClient</title><link>https://devzone.nordicsemi.com/thread/498921?ContentTypeID=1</link><pubDate>Mon, 19 Aug 2024 20:51:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c69308ae-2189-4520-8ab3-907a8335e9e0</guid><dc:creator>DevBear</dc:creator><description>&lt;p&gt;Sorry for the late answer, but yes I see my FROG service and I have tried restarting Bluetooth, took away the connection on my phone and still the attribute shown in the image above is there.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;With this code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/* main.c - Application main entry point */

/*
 * Copyright (c) 2020 SixOctets Systems
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;

#include &amp;lt;zephyr/kernel.h&amp;gt;
#include &amp;lt;zephyr/sys/printk.h&amp;gt;
#include &amp;lt;zephyr/sys/byteorder.h&amp;gt;

#include &amp;lt;zephyr/bluetooth/bluetooth.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/hci.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/conn.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/uuid.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/gatt.h&amp;gt;

/* --------------------- START OF FROG UUID:s ---------------- */

#define FROG_SERVICE BT_UUID_128_ENCODE(0x2016ec20, 0xb2eb, 0x11e5, 0xa307, 0x0002a5d5c51b)
// Notify characteristics
#define FROG_TXDATA_UUID BT_UUID_128_ENCODE(0x388706a0, 0xb2eb, 0x11e5, 0xa790, 0x0002a5d5c51b)

// Write without response characteristics
#define FROG_RXCREDIT BT_UUID_128_ENCODE(0x43802b40, 0xb2eb, 0x11e5, 0xb6e5, 0x0002a5d5c51b)


#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)

/* ----------------------------- END ------------------------- */


static int scan_start(void);

static struct bt_conn *default_conn;
//static struct bt_uuid_16 frog_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 struct bt_gatt_discover_params discover_params;
static struct bt_gatt_subscribe_params subscribe_params;

static double pow(double x, double y)
{
	double result = 1;

	if (y &amp;lt; 0) {
		y = -y;
		while (y--) {
			result /= x;
		}
	} else {
		while (y--) {
			result *= x;
		}
	}

	return result;
}

static uint8_t notify_func(struct bt_conn *conn,
			   struct bt_gatt_subscribe_params *params,
			   const void *data, uint16_t length)
{

	if (!data) {
		printk(&amp;quot;[UNSUBSCRIBED]\n&amp;quot;);
		params-&amp;gt;value_handle = 0U;
		return BT_GATT_ITER_STOP;
	}


	printf(&amp;quot;[NOTIFICATION]: Data from server %p.\n&amp;quot;, data);

	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(&amp;quot;Discover complete\n&amp;quot;);
		(void)memset(params, 0, sizeof(*params));
		return BT_GATT_ITER_STOP;
	}

	printk(&amp;quot;[ATTRIBUTE] handle %u\n&amp;quot;, attr-&amp;gt;handle);

	if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_FROG)) {
		printk(&amp;quot;Discovering TxDATA\n&amp;quot;);
		memcpy(&amp;amp;frog_discover_uuid, BT_UUID_TXDATA, sizeof(frog_discover_uuid));
		discover_params.uuid = &amp;amp;frog_discover_uuid.uuid;
		discover_params.start_handle = attr-&amp;gt;handle + 1;
		discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, &amp;amp;discover_params);
		if (err) {
			printk(&amp;quot;Discover failed (err %d)\n&amp;quot;, err);
		}
	} else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_FROG)) {
		printk(&amp;quot;Discovering CCC\n&amp;quot;);
		//memcpy(&amp;amp;frog_discover_uuid, BT_UUID_GATT_CCC, sizeof(frog_discover_uuid));
		discover_params.uuid = ccc_uuid;
		discover_params.start_handle = attr-&amp;gt;handle + 2;
		discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
		subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);

		err = bt_gatt_discover(conn, &amp;amp;discover_params);
		if (err) {
			printk(&amp;quot;Discover failed (err %d)\n&amp;quot;, err);
		}
	} else {
		subscribe_params.notify = notify_func;
		subscribe_params.value = BT_GATT_CCC_INDICATE;
		subscribe_params.ccc_handle = attr-&amp;gt;handle;

		err = bt_gatt_subscribe(conn, &amp;amp;subscribe_params);
		if (err &amp;amp;&amp;amp; err != -EALREADY) {
			printk(&amp;quot;Subscribe failed (err %d)\n&amp;quot;, err);
		} else {
			printk(&amp;quot;[SUBSCRIBED]\n&amp;quot;);
		}

		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(&amp;quot;Failed to connect to %s (%u)\n&amp;quot;, addr, conn_err);

		bt_conn_unref(default_conn);
		default_conn = NULL;

		scan_start();
		return;
	}

	printk(&amp;quot;Connected: %s\n&amp;quot;, addr);

	if (conn == default_conn) {
		memcpy(&amp;amp;frog_discover_uuid, BT_UUID_FROG, sizeof(frog_discover_uuid));
		discover_params.uuid = &amp;amp;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, &amp;amp;discover_params);
		if (err) {
			printk(&amp;quot;Discover failed(err %d)\n&amp;quot;, err);
			return;
		}
	}
}

static bool eir_found(struct bt_data *data, void *user_data)
{
	bt_addr_le_t *addr = user_data;
	int i;

	printk(&amp;quot;[AD]: %u data_len %u\n&amp;quot;, data-&amp;gt;type, data-&amp;gt;data_len);

	switch (data-&amp;gt;type) {
	case BT_DATA_UUID128_SOME:
	case BT_DATA_UUID128_ALL:
		if (data-&amp;gt;data_len % sizeof(uint16_t) != 0U) {
			printk(&amp;quot;AD malformed\n&amp;quot;);
			return true;
		}

		for (i = 0; i &amp;lt; data-&amp;gt;data_len; i += sizeof(uint16_t)) {
			const struct bt_uuid *uuid;
			uint16_t u16;
			int err;

			memcpy(&amp;amp;u16, &amp;amp;data-&amp;gt;data[i], sizeof(u16));
			uuid = BT_UUID_DECLARE_128(sys_le16_to_cpu(u16));
			if (bt_uuid_cmp(uuid, BT_UUID_FROG)) {
				continue;
			}

			err = bt_le_scan_stop();
			if (err) {
				printk(&amp;quot;Stop LE scan failed (err %d)\n&amp;quot;, err);
				continue;
			}

			err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
						BT_LE_CONN_PARAM_DEFAULT,
						&amp;amp;default_conn);
			if (err) {
				printk(&amp;quot;Create connection failed (err %d)\n&amp;quot;,
				       err);
				scan_start();
			}

			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(&amp;quot;[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i\n&amp;quot;,
	       dev, type, ad-&amp;gt;len, rssi);

	/* We&amp;#39;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(&amp;amp;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(&amp;quot;Disconnected: %s (reason 0x%02x)\n&amp;quot;, addr, reason);

	if (default_conn != conn) {
		return;
	}

	bt_conn_unref(default_conn);
	default_conn = NULL;

	err = scan_start();
	if (err) {
		printk(&amp;quot;Scanning failed to start (err %d)\n&amp;quot;, err);
	}
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = connected,
	.disconnected = disconnected,
};

int main(void)
{
	int err;

	err = bt_enable(NULL);
	if (err) {
		printk(&amp;quot;Bluetooth init failed (err %d)\n&amp;quot;, err);
		return 0;
	}

	printk(&amp;quot;Bluetooth initialized\n&amp;quot;);

	err = scan_start();

	if (err) {
		printk(&amp;quot;Scanning failed to start (err %d)\n&amp;quot;, err);
		return 0;
	}

	printk(&amp;quot;Scanning successfully started\n&amp;quot;);
	return 0;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The GATTServer is found but gets disconnected directly and no service is found.&lt;br /&gt;The server code is the same as the one originally posted.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Custom service GATTServer and GATTClient</title><link>https://devzone.nordicsemi.com/thread/497955?ContentTypeID=1</link><pubDate>Tue, 13 Aug 2024 08:04:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f07579a1-c740-4ac9-9c2a-e08208809e4e</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;Hi,&amp;nbsp;&lt;br /&gt;Please show the whole attribute table. Do you see your FROG service ?&amp;nbsp;&lt;br /&gt;If you flash a sample, for example the NUS sample, do you see the issue ?&amp;nbsp;&lt;br /&gt;I suspect that the Attribute table has been cached from the previous application you flashed on the board. You can try to turn off and on&amp;nbsp; Bluetooth on the phone, also remove bonding if any. Please try to use another phone or use NRF Connect on PC to check.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Our suggestion is that you go through our tutorial with the NUS sample to get familiar with the SDK before you move to your own code.&amp;nbsp;&lt;br /&gt;Converting NUS to your service should be straight forward after you managed to make the client/central firmware works.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Custom service GATTServer and GATTClient</title><link>https://devzone.nordicsemi.com/thread/497894?ContentTypeID=1</link><pubDate>Mon, 12 Aug 2024 21:05:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:69df9b49-1ce7-4506-a954-15294efcf85e</guid><dc:creator>DevBear</dc:creator><description>&lt;p&gt;Hello Hung!&lt;br /&gt;&lt;br /&gt;1: No that is the problem, if you see this screen shot from my nrf connect app:&lt;br /&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1723496228203v2.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;The service found is correct, but the attribute table is wrong right? I should not see the current time service here?&lt;br /&gt;I have watched these examples, is there something wrong in how I do it in my code?&lt;br /&gt;Yes I have looked at that course and this problem isn&amp;#39;t really discussed as I understand that a service needs to be announced and the characteristics hold attributes. But since I don&amp;#39;t use the cts at all I don&amp;#39;t understand why it shows up in my attribute table in nrf connect?&lt;br /&gt;&lt;br /&gt;2: Thank you! This is the first up to date useful guide I have been given. I will check this one and see if it helps me. However I am not interested in using the NUS so are all these functions in your tutorial applicable if you don&amp;#39;t want to use NUS?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Custom service GATTServer and GATTClient</title><link>https://devzone.nordicsemi.com/thread/497753?ContentTypeID=1</link><pubDate>Mon, 12 Aug 2024 09:20:34 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a85a7c64-0041-4089-ae87-f4fcfe6f6e1c</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;Hi Bjorn,&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;1. Please elaborate more on the issue you are seeing when removing cts. Could you point me to where you declare it ?&amp;nbsp;&lt;br /&gt;I would suggest to take a look at the peripheral_lbs sample or peripheral_uart sample as reference.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Have you looked at our Academy course for BLE ?&amp;nbsp;&lt;a href="https://academy.nordicsemi.com/courses/bluetooth-low-energy-fundamentals/"&gt;https://academy.nordicsemi.com/courses/bluetooth-low-energy-fundamentals/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;2. Usually the service discovery process only discover the service/characteristic that you look for. if you want to discover all service characteristic you will need to develop your own process. I would suggest you to go through this guide:&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/guides/nrf-connect-sdk-guides/b/software/posts/building-a-ble-application-on-ncs-sdk---contrasting-to-softdevice-based-ble-applications---part-2-central-role"&gt;Building a Bluetooth application on nRF Connect SDK - Contrasting to SoftDevice - Part 2 Central role&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>