<?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>Health Server and Health Client models.</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/95620/health-server-and-health-client-models</link><description>Hello All, 
 
 I am currently developing a mesh application with several nodes. I wish to add the health server faults for monitoring the nodes in the network. As of now I am able to receive the health messages with no faults detected. Health Client was</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 27 Jan 2023 11:49:49 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/95620/health-server-and-health-client-models" /><item><title>RE: Health Server and Health Client models.</title><link>https://devzone.nordicsemi.com/thread/406834?ContentTypeID=1</link><pubDate>Fri, 27 Jan 2023 11:49:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6b897b3c-a156-41b0-840b-07f3e2551f1e</guid><dc:creator>Sumedh L</dc:creator><description>&lt;p&gt;Hello Hieu,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I did refer to this code and it did help me set the faults as required.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Sumedh L.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Health Server and Health Client models.</title><link>https://devzone.nordicsemi.com/thread/406328?ContentTypeID=1</link><pubDate>Tue, 24 Jan 2023 16:31:22 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:763d5f0a-6070-46c4-9edd-1895de122755</guid><dc:creator>Hieu</dc:creator><description>&lt;p&gt;Hi Sumedh,&lt;/p&gt;
&lt;p&gt;Our apologies for the long wait. My sickness came at a bad time and coincided with Andreas&amp;#39; out of office period. &lt;br /&gt;I have now recovered and returned to office and will take over once more.&lt;/p&gt;
&lt;p&gt;A colleague helped me find some clue in the Bluetooth Mesh Shell application and we believe that the codes below serve as sample implementation.&lt;br /&gt;Could you please try to follow it and see if it works?&lt;br /&gt;Sorry I haven&amp;#39;t been able to verify it before sharing it with you, but I don&amp;#39;t want to keep&amp;nbsp;you waiting any longer.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;
// From zephyr/subsys/bluetooth/mesh/shell.c

static uint8_t cur_faults[BT_MESH_SHELL_CUR_FAULTS_MAX];
static uint8_t reg_faults[BT_MESH_SHELL_CUR_FAULTS_MAX * 2];

static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count)
{
	uint8_t i, limit = *count;

	for (i = 0U, *count = 0U; i &amp;lt; faults_size &amp;amp;&amp;amp; *count &amp;lt; limit; i++) {
		if (faults[i]) {
			*dst++ = faults[i];
			(*count)++;
		}
	}
}

static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id,
			 uint16_t *company_id, uint8_t *faults, uint8_t *fault_count)
{
	shell_print_ctx(&amp;quot;Sending current faults&amp;quot;);

	*test_id = 0x00;
	*company_id = BT_COMP_ID_LF;

	get_faults(cur_faults, sizeof(cur_faults), faults, fault_count);

	return 0;
}

static int fault_get_reg(struct bt_mesh_model *model, uint16_t cid,
			 uint8_t *test_id, uint8_t *faults, uint8_t *fault_count)
{
	if (cid != CONFIG_BT_COMPANY_ID) {
		shell_print_ctx(&amp;quot;Faults requested for unknown Company ID&amp;quot;
				&amp;quot; 0x%04x&amp;quot;, cid);
		return -EINVAL;
	}

	shell_print_ctx(&amp;quot;Sending registered faults&amp;quot;);

	*test_id = 0x00;

	get_faults(reg_faults, sizeof(reg_faults), faults, fault_count);

	return 0;
}

static int fault_clear(struct bt_mesh_model *model, uint16_t cid)
{
	if (cid != CONFIG_BT_COMPANY_ID) {
		return -EINVAL;
	}

	(void)memset(reg_faults, 0, sizeof(reg_faults));

	return 0;
}

static int fault_test(struct bt_mesh_model *model, uint8_t test_id,
		      uint16_t cid)
{
	if (cid != CONFIG_BT_COMPANY_ID) {
		return -EINVAL;
	}

	if (test_id != 0x00) {
		return -EINVAL;
	}

	return 0;
}

static const struct bt_mesh_health_srv_cb health_srv_cb = {
	.fault_get_cur = fault_get_cur,
	.fault_get_reg = fault_get_reg,
	.fault_clear = fault_clear,
	.fault_test = fault_test,
};

static int cmd_add_fault(const struct shell *shell, size_t argc, char *argv[])
{
	uint8_t fault_id;
	uint8_t i;
	struct bt_mesh_elem *elem;
	int err = 0;

	elem = primary_element();
	if (elem == NULL) {
		shell_print(shell, &amp;quot;Element not found!&amp;quot;);
		return -EINVAL;
	}

	fault_id = shell_strtoul(argv[1], 0, &amp;amp;err);
	if (err) {
		shell_warn(shell, &amp;quot;Unable to parse input string argument&amp;quot;);
		return err;
	}

	if (!fault_id) {
		shell_print(shell, &amp;quot;The Fault ID must be non-zero!&amp;quot;);
		return -EINVAL;
	}

	for (i = 0U; i &amp;lt; sizeof(cur_faults); i++) {
		if (!cur_faults[i]) {
			cur_faults[i] = fault_id;
			break;
		}
	}

	if (i == sizeof(cur_faults)) {
		shell_print(shell, &amp;quot;Fault array is full. Use \&amp;quot;del-fault\&amp;quot; to &amp;quot;
			    &amp;quot;clear it&amp;quot;);
		return 0;
	}

	for (i = 0U; i &amp;lt; sizeof(reg_faults); i++) {
		if (!reg_faults[i]) {
			reg_faults[i] = fault_id;
			break;
		}
	}

	if (i == sizeof(reg_faults)) {
		shell_print(shell, &amp;quot;No space to store more registered faults&amp;quot;);
	}

	bt_mesh_fault_update(elem);

	return 0;
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Please let me know if there are any problems.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Hieu&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Health Server and Health Client models.</title><link>https://devzone.nordicsemi.com/thread/406140?ContentTypeID=1</link><pubDate>Tue, 24 Jan 2023 03:40:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4d1bffc4-7f97-4c54-83e3-259e63c8313a</guid><dc:creator>Sumedh L</dc:creator><description>&lt;p&gt;Hello Andreas,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Is there any update regarding the topic? We are still waiting for the response.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Sumedh L.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Health Server and Health Client models.</title><link>https://devzone.nordicsemi.com/thread/405681?ContentTypeID=1</link><pubDate>Thu, 19 Jan 2023 13:12:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e19704d5-ad03-496e-86a1-63cfa225988e</guid><dc:creator>AHaug</dc:creator><description>&lt;p&gt;Hi,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Unfortunately I did not have time to handle this case before I&amp;#39;m going out of office, but I will get back to it next week. Apologies for the inconvinience&lt;/p&gt;
&lt;p&gt;Kind regards,&lt;br /&gt;Andreas&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Health Server and Health Client models.</title><link>https://devzone.nordicsemi.com/thread/405191?ContentTypeID=1</link><pubDate>Tue, 17 Jan 2023 10:20:13 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f2804e01-b53d-4e20-91e0-bb4c22daba73</guid><dc:creator>Sumedh L</dc:creator><description>&lt;p&gt;Hello Andreas,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Thank you for responding.&lt;/p&gt;
&lt;p&gt;I have&amp;nbsp;copied the following code from the sensor server sample provided.&amp;nbsp;My main issue with this code is understanding how I am supposed to send the faults to the client. I have seen the faults and warnings mentioned in nrf/include/bluetooth/mesh/properties.h. I wish to use few of these codes send the health details of my node to the client.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static struct k_work_delayable attention_blink_work;
static bool attention;

static void attention_blink(struct k_work *work)
{
	static int idx;
	const uint8_t pattern[] = {
#if DT_NODE_EXISTS(DT_ALIAS(led0))
		BIT(0),
#endif
#if DT_NODE_EXISTS(DT_ALIAS(led1))
		BIT(1),
#endif
#if DT_NODE_EXISTS(DT_ALIAS(led2))
		BIT(2),
#endif
#if DT_NODE_EXISTS(DT_ALIAS(led3))
		BIT(3),
#endif
	};

	if (attention) {
		dk_set_leds(pattern[idx++ % ARRAY_SIZE(pattern)]);
		k_work_reschedule(&amp;amp;attention_blink_work, K_MSEC(100));		//Changed the Blinking speed for the attention callback. SL
	} else {
		dk_set_leds(DK_NO_LEDS_MSK);
	}
}

/**
 * @brief: This function will enable the attention of the node.
 * This is the function that is executed during identification of the node in the nRF Mesh application.
*/
static void attention_on(struct bt_mesh_model *mod)
{
	attention = true;
	k_work_reschedule(&amp;amp;attention_blink_work, K_NO_WAIT);
}

/**
 * @brief: This function will disable the attention of the node.
 * This is the function that is executed during identification of the node in the nRF Mesh application.
*/
static void attention_off(struct bt_mesh_model *mod)
{
	/* Will stop rescheduling blink timer */
	attention = false;
}

static const struct bt_mesh_health_srv_cb health_srv_cb = {
	.attn_on = attention_on,
	.attn_off = attention_off,
};

static struct bt_mesh_health_srv health_srv = {
	.cb = &amp;amp;health_srv_cb,
};

BT_MESH_HEALTH_PUB_DEFINE(health_pub, 0);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;On the Client end I implemented the following code for health client. I based this code from the Mesh_Provisioner sample provided. Now I wish to see the sent codes from the node here.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static void current_health_status(struct bt_mesh_health_cli *cli, uint16_t addr,
				  uint8_t test_id, uint16_t cid, uint8_t *faults,
				  size_t fault_count)
{
	size_t i;
	
	printk(&amp;quot;\nHealth Current Status from Node ID: %d\n&amp;quot;, addr);
	
	if (!fault_count) {
		printk(&amp;quot;\nHealth Test ID 0x%02x Company ID 0x%04x: no faults\n&amp;quot;,
		       test_id, cid);
		return;
	}

	printk(&amp;quot;Health Test ID 0x%02x Company ID 0x%04x Fault Count %zu:\n&amp;quot;,
	       test_id, cid, fault_count);

	for (i = 0; i &amp;lt; fault_count; i++) {
		printk(&amp;quot;\t0x%02x\n&amp;quot;, faults[i]);
	}
}

static struct bt_mesh_health_cli health_client = {
	.current_status = current_health_status,
};&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;It would be useful to get some sample or guide on how to add these faults and send them as well as clear them if necessary.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Sumedh.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Health Server and Health Client models.</title><link>https://devzone.nordicsemi.com/thread/405172?ContentTypeID=1</link><pubDate>Tue, 17 Jan 2023 09:11:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8c811122-eaee-463f-93a3-a3fc291e84ab</guid><dc:creator>AHaug</dc:creator><description>&lt;p&gt;Hi,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Hieu is out of office this week so I will help you progress this case in the meanwhile.&lt;/p&gt;
[quote user=""]As of now I am able to receive the health messages with no faults detected. Health Client was referred from the &amp;#39;P&lt;span&gt;rovisioner Sample&amp;#39;. example where the callbacks printed out the detected errors.&lt;/span&gt;[/quote]
&lt;p&gt;Could you either send us a minimal sample that reproduces how far you&amp;#39;ve come in setting up the health server/client models in your application or send us steps for how to recreate what you&amp;#39;ve done?&lt;/p&gt;
&lt;p&gt;Kind regards,&lt;br /&gt;Andreas&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Health Server and Health Client models.</title><link>https://devzone.nordicsemi.com/thread/404881?ContentTypeID=1</link><pubDate>Sat, 14 Jan 2023 03:37:52 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e95311d5-d1f9-4a35-b0b4-a7eb2ca3fdd2</guid><dc:creator>Sumedh L</dc:creator><description>&lt;p&gt;Thank you for your response Hieu.&lt;/p&gt;
&lt;p&gt;We&amp;#39;ll be waiting for any help on this topic.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Sumedh L.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Health Server and Health Client models.</title><link>https://devzone.nordicsemi.com/thread/404812?ContentTypeID=1</link><pubDate>Fri, 13 Jan 2023 13:27:58 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6fb90fcb-35aa-4c2e-9d4c-da875bbd2494</guid><dc:creator>Hieu</dc:creator><description>&lt;p&gt;Hi Sumedh,&lt;/p&gt;
&lt;p&gt;I will need more time to look into this. Unless someone from the community already helped you by then, I will respond to you latest by the end of Wednesday Jan 18.&lt;/p&gt;
&lt;p&gt;Hieu&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>