<?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>app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/94614/app_usbd_cdc_acm_write-multiple-write</link><description>Hello i am using an nrf52840 s140 and i am trying to write a specific event when takes place to the usb port. I am using the usbd_uart example. 
 It works fine for the first write command but when i am trying to write for a second time it just writes</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 12 Dec 2022 08:26:51 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/94614/app_usbd_cdc_acm_write-multiple-write" /><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/400066?ContentTypeID=1</link><pubDate>Mon, 12 Dec 2022 08:26:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8f53971b-017e-40bb-badd-f5f3b02e06ba</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Convert the hex data to ascii(for instance using snprintf) so that everything you send to the terminal is ascii&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/400065?ContentTypeID=1</link><pubDate>Mon, 12 Dec 2022 08:22:40 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a0f4b319-373f-4ec5-b573-cce47e012fe5</guid><dc:creator>kleanthise</dc:creator><description>&lt;p&gt;Thanks a lot i have modified the code and now the counter is printed over to terminal. However the string is presented as an ascii. Is there a way to convert it to hex ?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I have for example one condition in hex that is the command activation (0x01) when the user sends that command via BLE the code is activated and it runs a sequence. However when i switch my terminal to ascii i can only monitor the commands received from the counter and not the starting command. Is there a way to print the hex command while looking at ascii characters ?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/400051?ContentTypeID=1</link><pubDate>Mon, 12 Dec 2022 06:46:29 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a40584d2-7d52-4ce7-8fab-b94988d51741</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;The&amp;nbsp;app_usbd_cdc_acm_write() will write to USB CDC ACM, yes. So you should see it on your computer (provided things are done correctly and you have a terminal on your computer connected to that virtual UART port). You can see a simple example of&amp;nbsp;the same&amp;nbsp;in&amp;nbsp;examples/peripheral/usbd_cdc_acm/main.c:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;            static int  frame_counter;

            size_t size = sprintf(m_tx_buffer, &amp;quot;Hello USB CDC FA demo: %u\r\n&amp;quot;, frame_counter);

            ret = app_usbd_cdc_acm_write(&amp;amp;m_app_cdc_acm, m_tx_buffer, size);
            if (ret == NRF_SUCCESS)
            {
                ++frame_counter;
            }&lt;/pre&gt;&lt;/p&gt;
[quote user="kleanthise"]my terminal connection[/quote]
&lt;p&gt;If this is terminal via USB CDC ACM, then the above is the way to do it. If it is via UART or NUS, then other approaches are needed (see relevant&amp;nbsp;samples for that). You have most of the code in your project though, the main thing should be to fix up the generic C programming mistakes we have discussed before in this thread.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399951?ContentTypeID=1</link><pubDate>Fri, 09 Dec 2022 13:39:31 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:433bcf4e-ad7c-4e4f-920e-eb6a2bc07a3e</guid><dc:creator>kleanthise</dc:creator><description>&lt;p&gt;This should be transferred over to the usb and printed on my computer terminal. I thought that this command :&amp;nbsp;ret = app_usbd_cdc_acm_write(&amp;amp;m_app_cdc_acm, buf, j); would transfer the data over to my usb port and be printed on the terminal but this is not the case.&lt;/p&gt;
&lt;p&gt;Is it correct the way i understood it ? or shall i use a different command to print the data to my terminal connection ?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399949?ContentTypeID=1</link><pubDate>Fri, 09 Dec 2022 13:35:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:24a3dfae-5bb9-4381-b097-b19566f901b3</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Where should this be printed? What you do here (except for the issues described in my previous post) is to take the integer value in the counter variable and convert it to a string in the buf char array. So now it resides as a C string in buf. But it is not printed by itself unless you do so.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399820?ContentTypeID=1</link><pubDate>Fri, 09 Dec 2022 06:44:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:47a1e70f-a69e-495a-aed3-80131f92d212</guid><dc:creator>kleanthise</dc:creator><description>&lt;p&gt;Ok now makes more sense. thanks a lot for clarifying this.&lt;/p&gt;
&lt;p&gt;The value of counter that should be incrementing from 1,2,3,4,5 is still not shown in the terminal. Instead i am looking at some values that i do not understand from where they are coming.&lt;/p&gt;
&lt;p&gt;shouldnt the command int j = sprintf(buf, sizeof(buf), &amp;quot;s%&amp;quot; , counter) be printed on the terminal ? or maybe i am missing something ?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399741?ContentTypeID=1</link><pubDate>Thu, 08 Dec 2022 14:41:25 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:19f68d35-96c2-4f34-8381-78ee0668851e</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;No, there are a number of issues here. Both what I pointed to before, and then from this snippet. Let&amp;#39;s start with this line:&lt;/p&gt;
&lt;p&gt;static char buf[sizeof(counter)];&lt;/p&gt;
&lt;p&gt;Here you make the buffer sizeof(counter),&amp;nbsp;and counter is an integer, so this is 4. And a string is 0 terminated, so this can hold 3 characters + the nullt ermination. So the largest number you can hav here as ASCII is &amp;quot;999&amp;quot;. If that is OK, then it is fine. If not, make the buffer bigger.&lt;/p&gt;
&lt;p&gt;Then the next line:&lt;/p&gt;
&lt;p&gt;int j = snprintf(buf, sizeof(buf), &amp;quot;%s&amp;quot;, counter);&lt;/p&gt;
&lt;p&gt;This in itself looks good. Here the j that is returned from snprintf hold the actual length of the string (not including the null termination). It does not hold the string, which is in buf. So it makes no sense to pass the address to j where you should have passed the buffer in this line:&lt;/p&gt;
&lt;p&gt;ret = app_usbd_cdc_acm_write(&amp;amp;m_app_cdc_acm, &amp;amp;j, length);&lt;/p&gt;
&lt;p&gt;This should instead have been something like this:&lt;/p&gt;
&lt;p&gt;ret = app_usbd_cdc_acm_write(&amp;amp;m_app_cdc_acm, buff, j);&lt;/p&gt;
&lt;p&gt;(assuming you don&amp;#39;t want to include the null termination. If you want it, it would be j+1 as the last parameter.&lt;/p&gt;
&lt;p&gt;These are generic C programming issues (with handling pointers, arrays and C strings). So I suggest you look a bit into that before continuing with this.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399696?ContentTypeID=1</link><pubDate>Thu, 08 Dec 2022 14:00:52 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a95a93d8-9712-406a-b14a-06e34e4a3215</guid><dc:creator>kleanthise</dc:creator><description>&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;if (p_evt-&amp;gt;type == UART_RX_DATA) {
		ret_code_t ret;
		//memcpy(&amp;amp;counter, p_evt-&amp;gt;params.tx_data.p_data, p_evt-&amp;gt;params.tx_data.length);
		// uint16_t length = p_evt-&amp;gt;params.tx_data.length;

		NRF_LOG_INFO(&amp;quot;UART_TX&amp;quot;);

		static char buf[sizeof(counter)];
		int j = snprintf(buf, sizeof(buf), &amp;quot;%s&amp;quot;, counter);
		uint16_t length = strlen(buf);
		ret = app_usbd_cdc_acm_write(&amp;amp;m_app_cdc_acm, &amp;amp;j, length);

		if (ret != NRF_SUCCESS) {
			NRF_LOG_INFO(&amp;quot;CDC ACM unavailable, data received: %d&amp;quot;, counter);
		}
	}&lt;/pre&gt; I have modified my code inside nus_data_handler . Now some data are passing over to terminal but again are wrong. Have i done the conversion from integer to string correct ?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Thanks&lt;br /&gt;Kle&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399609?ContentTypeID=1</link><pubDate>Thu, 08 Dec 2022 10:27:12 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e621b407-d1fe-4069-a1e2-fe8c4944a342</guid><dc:creator>kleanthise</dc:creator><description>&lt;p&gt;I think it is from NUS, for example when i am sending from the nrfconnect application the command 0x01 which i have set as the command for activating this counter, i can see that command on terminal.&lt;/p&gt;
&lt;p&gt;I will try and convert the counter to string and run it again and see if that resolves this issue.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Thanks&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399606?ContentTypeID=1</link><pubDate>Thu, 08 Dec 2022 10:13:31 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:057850e3-7569-40fd-b9de-91b2932d6191</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;I am still not sure where you see the issue though. The UART terminal on your PC, is that observing the UART output of nRF (log output), or is it form NUS? In any case, there is something fishy here:&lt;/p&gt;
&lt;p&gt;Your counter is a integer:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static int counter = 0;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;And you print it as if it was a string, which is clearly wrong:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;NRF_LOG_INFO(&amp;quot;CDC ACM unavailable, data received: %s&amp;quot;, counter);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Here you should use %d or %i instead of %s (which is for a string). This is just in the log when there is an error though, but it makes me wonder if you have&amp;nbsp;other similar mistakes.&lt;/p&gt;
&lt;p&gt;Along that line, I also don&amp;#39;t understand your&amp;nbsp;ble_progress_update(). Here you send the integer value (now an uint8) without converting it to ascii. As you take the size of it and handle it as if it was an array (which it is not, and as an uint8 the size is always 1) you are on to something, but it is only half-done. It is expectd that you get garbeled data as you are effectivly sending an uint8 (which is your counter stripped down to 8 bit) which is not a character, and that is all.&lt;/p&gt;
&lt;p&gt;First of all, you need to convert your ocunter to a string,. You could do that in your&amp;nbsp;ble_progress_update() or before, that is up to you. Secondly, I don&amp;#39;t understand why you use the lower level sd_ble_gatts API for this, as you are using NUS. There are NUS functions for sending a string. Just look at the ble_app_uart sample. Essentially, convert your counter to a string (using for instance &lt;code&gt;snprintf(counter_string, sizeof(counter_string)&amp;quot;%s&amp;quot;, counter)&lt;/code&gt;), and send it with&amp;nbsp;ble_nus_data_send(). No need to re-implement things that is already there. That is both a wast of time and error prone.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399468?ContentTypeID=1</link><pubDate>Wed, 07 Dec 2022 14:26:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:53a207fb-9f3b-4ef6-8f6f-a307570ebb10</guid><dc:creator>kleanthise</dc:creator><description>&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;if (p_evt-&amp;gt;type == UART_RX_DATA) {
		ret_code_t ret;
		//memcpy(&amp;amp;counter, p_evt-&amp;gt;params.tx_data.p_data, p_evt-&amp;gt;params.tx_data.length);
		uint16_t length = p_evt-&amp;gt;params.tx_data.length;
		if (length + sizeof(ENDLINE_STRING) &amp;lt; BLE_NUS_MAX_DATA_LEN) {
			//memcpy(&amp;amp;counter + length, ENDLINE_STRING, sizeof(ENDLINE_STRING));
			length += sizeof(ENDLINE_STRING);
		}
		NRF_LOG_INFO(&amp;quot;UART_TX&amp;quot;);
		//nrf_delay_ms(100);
		char buffer[sizeof(counter)];
		int j = sprintf(buffer, &amp;quot;Step event %d&amp;quot;, counter);
                ret = app_usbd_cdc_acm_write(&amp;amp;m_app_cdc_acm, &amp;amp;j, length);

		if (ret != NRF_SUCCESS) {
			NRF_LOG_INFO(&amp;quot;CDC ACM unavailable, data received: %s&amp;quot;, counter);
		}
	}
}&lt;/pre&gt;i have modified the code inside nus_data_handler for my custom event as attached but now i am watching on the terminal only 0 0 0 0 0 .&lt;/p&gt;
&lt;p&gt;I thought because counter is an integer maybe that was the reason and i have converted it into string using sprintf.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399441?ContentTypeID=1</link><pubDate>Wed, 07 Dec 2022 13:45:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:17275889-2436-41a0-b291-899bf71aae80</guid><dc:creator>kleanthise</dc:creator><description>&lt;p&gt;Hello Einar,&lt;/p&gt;
&lt;p&gt;Yes of course,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The data i am monitoring them using realterm on windows. i have tried both ascii and hex for the format on the terminal but they are always shown distorted.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The data i am testing with is a counter that counts from 1 to 5 and prints&amp;nbsp;using this command on the debugger NRF_LOG_INFO(&amp;quot;Step event %d&amp;quot;, counter) through a custom timer that when it reaches step 5 it stops the counter. This updates the characteristic value inside the ble_nus custom file i have attached on my first attachment.&amp;nbsp;I would like to transfer this information via usbd to my computer.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I can see that data are coming over but they come with some random characters.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Please let me know if any further information is required.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399438?ContentTypeID=1</link><pubDate>Wed, 07 Dec 2022 13:37:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1a672f52-ff93-45b4-aa03-f54cef1debe1</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Can you elaborate a bit more?&lt;/p&gt;
&lt;p&gt;Firstly, where exactly do you see the corrupt data? Is it in a terminal window of another device and you are looking at the data that was received from the device over NUS? Or somewhere else?&lt;/p&gt;
&lt;p&gt;Secondly, what is the data you are testing with? As you see the right data with a debugger but not on a terminal screen, the first thing that comes to mind is that it is not ASCII but the terminal expects ASCII and print the data as if it was&amp;nbsp;ASCII characters.&lt;/p&gt;
&lt;p&gt;Another common issue with &amp;quot;Random&amp;quot; data is something like a dangling pointer, buffer overflow or something else. It would make sense to debug a bit more to narrow down first though (or if you have, just clarify more here what you have found).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399406?ContentTypeID=1</link><pubDate>Wed, 07 Dec 2022 12:31:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3fb32131-a39b-4a93-9dc9-484c8e96c343</guid><dc:creator>kleanthise</dc:creator><description>&lt;p&gt;If it helps the issue is happening in the function nus_data_handler . I have a counter that is updating a characteristic value and i would like to send that value to the terminal via usb. When i am looking at the debug screen of segger everything seems to be working fine. However on the terminal screen the data send are wrong&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: app_usbd_cdc_acm_write multiple write</title><link>https://devzone.nordicsemi.com/thread/399366?ContentTypeID=1</link><pubDate>Wed, 07 Dec 2022 10:09:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4b4c7962-5acc-493d-adcc-cf67137e4dc7</guid><dc:creator>kleanthise</dc:creator><description>&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

#include &amp;quot;app_timer.h&amp;quot;
#include &amp;quot;app_uart.h&amp;quot;
#include &amp;quot;app_util_platform.h&amp;quot;
#include &amp;quot;ble_advdata.h&amp;quot;
#include &amp;quot;ble_advertising.h&amp;quot;
#include &amp;quot;ble_conn_params.h&amp;quot;
#include &amp;quot;ble_hci.h&amp;quot;
#include &amp;quot;ble_nus_custom.h&amp;quot;
#include &amp;quot;bsp_btn_ble.h&amp;quot;
#include &amp;quot;nordic_common.h&amp;quot;
#include &amp;quot;nrf.h&amp;quot;
#include &amp;quot;nrf_ble_gatt.h&amp;quot;
#include &amp;quot;nrf_drv_clock.h&amp;quot;
#include &amp;quot;nrf_pwr_mgmt.h&amp;quot;
#include &amp;quot;nrf_sdh.h&amp;quot;
#include &amp;quot;nrf_sdh_ble.h&amp;quot;
#include &amp;quot;nrf_sdh_soc.h&amp;quot;

#include &amp;quot;nrf_log.h&amp;quot;
#include &amp;quot;nrf_log_ctrl.h&amp;quot;
#include &amp;quot;nrf_log_default_backends.h&amp;quot;

#include &amp;quot;nrf_delay.h&amp;quot;
#include &amp;quot;nrf_drv_clock.h&amp;quot;
#include &amp;quot;nrf_drv_power.h&amp;quot;
#include &amp;quot;nrf_drv_usbd.h&amp;quot;
#include &amp;quot;nrf_gpio.h&amp;quot;

#include &amp;quot;app_error.h&amp;quot;
#include &amp;quot;app_usbd.h&amp;quot;
#include &amp;quot;app_usbd_cdc_acm.h&amp;quot;
#include &amp;quot;app_usbd_core.h&amp;quot;
#include &amp;quot;app_usbd_serial_num.h&amp;quot;
#include &amp;quot;app_usbd_string_desc.h&amp;quot;
#include &amp;quot;app_util.h&amp;quot;

#include &amp;quot;config.h&amp;quot;

#define LED_BLE_NUS_CONN (BSP_BOARD_LED_0)
#define LED_BLE_NUS_RX (BSP_BOARD_LED_1)
#define LED_CDC_ACM_CONN (BSP_BOARD_LED_2)
#define LED_CDC_ACM_RX (BSP_BOARD_LED_3)

#define LED_BLINK_INTERVAL 800

APP_TIMER_DEF(m_blink_ble);
APP_TIMER_DEF(m_blink_cdc);
APP_TIMER_DEF(m_notification_timer_id);

//---------------------------------------------------------------------------------------------------------------------------

#define COMMAND_ACTIVATION 0x01
#define COMMAND_TERMINATION 0x02
bool m_device_state = true;
static int counter = 0;
int number_of_steps = 5;

/**
 * @brief App timer handler for blinking the LEDs.
 *
 * @param p_context LED to blink.
 */
void blink_handler(void *p_context)
{
	bsp_board_led_invert((uint32_t)p_context);
}

#define ENDLINE_STRING &amp;quot;\r\n&amp;quot;

/**
 * @brief Function for assert macro callback.
 *
 * @details This function will be called in case of an assert in the SoftDevice.
 *
 * @warning This handler is an example only and does not fit a final product. You need to analyze
 *          how your product is supposed to react in case of an assert.
 * @warning On assert from the SoftDevice, the system can only recover on reset.
 *
 * @param[in] line_num    Line number of the failing ASSERT call.
 * @param[in] p_file_name File name of the failing ASSERT call.
 */
void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name)
{
	app_error_handler(DEAD_BEEF, line_num, p_file_name);
}

static void app_timer_handler(void *p_context)
{

	UNUSED_PARAMETER(p_context);
	ret_code_t err_code;
	// uint16_t ResData[7] = {0,1,0,0,0,1,1};
	static int8_t results_value[] = {1, 1, 0, 1, 1, 1, 1}; //{ResData[0], ResData[1], ResData[2], ResData[3], ResData[4], ResData[5], ResData[6]};
	counter++;

	NRF_LOG_INFO(&amp;quot;Step event %d&amp;quot;, counter);

	err_code = ble_progress_update(&amp;amp;m_nus, counter);
	APP_ERROR_CHECK(err_code);

	if (counter == number_of_steps) {

		err_code = ble_results_update(&amp;amp;m_nus, results_value);
		APP_ERROR_CHECK(err_code);
		NRF_LOG_INFO(&amp;quot;Samples analysis is finished&amp;quot;);
		NRF_LOG_INFO(&amp;quot;Results&amp;quot;);
		NRF_LOG_INFO(&amp;quot;-------&amp;quot;);
		NRF_LOG_INFO(&amp;quot;E.Coli 0157 %d&amp;quot;, false);
		NRF_LOG_INFO(&amp;quot;Salmonella %d&amp;quot;, false);
		NRF_LOG_INFO(&amp;quot;Imidacloprid %d&amp;quot;, true);
		NRF_LOG_INFO(&amp;quot;Acrylamide %d&amp;quot;, false);
		NRF_LOG_INFO(&amp;quot;Ochratoxin A %d&amp;quot;, false);
		NRF_LOG_INFO(&amp;quot;Deoxynivalenol %d&amp;quot;, false);
		NRF_LOG_INFO(&amp;quot;Aflatoxin B2 %d&amp;quot;, true);

		app_timer_stop(m_notification_timer_id);
		m_device_state = false;
	}
}

/** @brief Function for initializing the timer module. */
static void timers_init(void)
{
	ret_code_t err_code = app_timer_init();
	APP_ERROR_CHECK(err_code);
	err_code = app_timer_create(&amp;amp;m_blink_ble, APP_TIMER_MODE_REPEATED, blink_handler);
	APP_ERROR_CHECK(err_code);
	err_code = app_timer_create(&amp;amp;m_blink_cdc, APP_TIMER_MODE_REPEATED, blink_handler);
	APP_ERROR_CHECK(err_code);
	err_code = app_timer_create(&amp;amp;m_notification_timer_id, APP_TIMER_MODE_REPEATED, app_timer_handler);
	APP_ERROR_CHECK(err_code);
}

/**
 * @brief Function for the GAP initialization.
 *
 * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of
 *          the device. It also sets the permissions and appearance.
 */
static void gap_params_init(void)
{
	uint32_t err_code;
	ble_gap_conn_params_t gap_conn_params;
	ble_gap_conn_sec_mode_t sec_mode;

	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;sec_mode);

	err_code = sd_ble_gap_device_name_set(&amp;amp;sec_mode,
	    (const uint8_t *)DEVICE_NAME,
	    strlen(DEVICE_NAME));
	APP_ERROR_CHECK(err_code);

	memset(&amp;amp;gap_conn_params, 0, sizeof(gap_conn_params));

	gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
	gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
	gap_conn_params.slave_latency = SLAVE_LATENCY;
	gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;

	err_code = sd_ble_gap_ppcp_set(&amp;amp;gap_conn_params);
	APP_ERROR_CHECK(err_code);
}

static void on_cus_evt(ble_nus_t *p_nus_service,
    ble_nus_evt_t *p_evt)
{
	ret_code_t err_code;

	switch (p_evt-&amp;gt;type) {
	case BLE_CUS_EVT_NOTIFICATION_ENABLED:

		err_code = app_timer_start(m_notification_timer_id, COUNTER_INTERVAL, NULL);
		APP_ERROR_CHECK(err_code);
		break;

	case BLE_CUS_EVT_NOTIFICATION_DISABLED:

		err_code = app_timer_stop(m_notification_timer_id);
		APP_ERROR_CHECK(err_code);
		break;

	case BLE_CUS_EVT_CONNECTED:
		break;

	case BLE_CUS_EVT_DISCONNECTED:
		break;

	default:
		// No implementation needed.
		break;
	}
}

/**
 * @brief Function for handling the data from the Nordic UART Service.
 *
 * @details This function processes the data received from the Nordic UART BLE Service and sends
 *          it to the USBD CDC ACM module.
 *
 * @param[in] p_evt Nordic UART Service event.
 */

static void nus_data_handler(ble_nus_evt_t *p_evt)
{
	ret_code_t err_code;
	if (p_evt-&amp;gt;type == BLE_NUS_EVT_RX_DATA) {

		// bsp_board_led_invert(LED_BLE_NUS_RX);
		NRF_LOG_DEBUG(&amp;quot;Received data from BLE NUS. Writing data on CDC ACM.&amp;quot;);
		NRF_LOG_HEXDUMP_DEBUG(p_evt-&amp;gt;params.rx_data.p_data, p_evt-&amp;gt;params.rx_data.length);
		memcpy(m_nus_data_array, p_evt-&amp;gt;params.rx_data.p_data, p_evt-&amp;gt;params.rx_data.length);

		//// Add endline characters
		uint16_t length = p_evt-&amp;gt;params.rx_data.length;
		if (length + sizeof(ENDLINE_STRING) &amp;lt; BLE_NUS_MAX_DATA_LEN) {
			memcpy(m_nus_data_array + length, ENDLINE_STRING, sizeof(ENDLINE_STRING));
			length += sizeof(ENDLINE_STRING);
		}

		if (p_evt-&amp;gt;params.rx_data.p_data[0] == COMMAND_ACTIVATION) {
			if (m_device_state) {
				NRF_LOG_INFO(&amp;quot;Device is activated.&amp;quot;);
				err_code = app_timer_start(m_notification_timer_id, COUNTER_INTERVAL, NULL);
				APP_ERROR_CHECK(err_code);
				while (app_uart_put(COMMAND_ACTIVATION) != NRF_SUCCESS)
					;
			}
		} else {
			if (p_evt-&amp;gt;params.rx_data.p_data[0] == COMMAND_TERMINATION) {
				m_device_state = false;
			}
			if (m_device_state == false) {
				NRF_LOG_INFO(&amp;quot;Device is not activated.&amp;quot;);
				while (app_uart_put(COMMAND_TERMINATION) != NRF_SUCCESS)
					;
				err_code = app_timer_stop(m_notification_timer_id);
				APP_ERROR_CHECK(err_code);
			}
		}

		// Send data through CDC ACM
		ret_code_t ret = app_usbd_cdc_acm_write(&amp;amp;m_app_cdc_acm,
		    m_nus_data_array,
		    length);

		if (ret != NRF_SUCCESS) {
			NRF_LOG_INFO(&amp;quot;CDC ACM unavailable, data received: %s&amp;quot;, m_nus_data_array);
		}
	}

	if (p_evt-&amp;gt;type == UART_RX_DATA) {
		ret_code_t ret;
		uint16_t length = p_evt-&amp;gt;params.tx_data.length;
		if (length + sizeof(ENDLINE_STRING) &amp;lt; BLE_NUS_MAX_DATA_LEN) {
			// memcpy(m_nus_data_array + length, ENDLINE_STRING, sizeof(ENDLINE_STRING));
			length += sizeof(ENDLINE_STRING);
		}
		NRF_LOG_INFO(&amp;quot;UART_TX&amp;quot;);
                nrf_delay_ms(100);
		ret = app_usbd_cdc_acm_write(&amp;amp;m_app_cdc_acm, m_nus_data_array, length);
		if (ret != NRF_SUCCESS) {
			NRF_LOG_INFO(&amp;quot;CDC ACM unavailable, data received: %s&amp;quot;, counter);
		}
	}
}

/** @brief Function for initializing services that will be used by the application. */
static void services_init(void)
{
	uint32_t err_code;
	// ble_nus_init_t nus_init;

	ble_nus_init_t nus_init = {0};
	// memset(&amp;amp;nus_init, 0, sizeof(nus_init));
	/* Initialize Queued Write Module.*/

	nus_init.data_handler = nus_data_handler;

	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.results_char_attr_md.cccd_write_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.results_char_attr_md.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.results_char_attr_md.write_perm);

	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.progress_char_attr_md.cccd_write_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.progress_char_attr_md.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.progress_char_attr_md.write_perm);

	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.rx_char_attr_md.cccd_write_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.rx_char_attr_md.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.rx_char_attr_md.write_perm);

	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.tx_char_attr_md.cccd_write_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.tx_char_attr_md.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;nus_init.tx_char_attr_md.write_perm);

	err_code = ble_nus_init(&amp;amp;m_nus, &amp;amp;nus_init);
	APP_ERROR_CHECK(err_code);
}

/**
 * @brief Function for handling errors from the Connection Parameters module.
 *
 * @param[in] nrf_error  Error code containing information about what went wrong.
 */
static void conn_params_error_handler(uint32_t nrf_error)
{
	APP_ERROR_HANDLER(nrf_error);
}

/** @brief Function for initializing the Connection Parameters module. */
static void conn_params_init(void)
{
	uint32_t err_code;
	ble_conn_params_init_t cp_init;

	memset(&amp;amp;cp_init, 0, sizeof(cp_init));

	cp_init.p_conn_params = NULL;
	cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
	cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
	cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
	cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
	cp_init.disconnect_on_fail = true;
	cp_init.evt_handler = NULL;
	cp_init.error_handler = conn_params_error_handler;

	err_code = ble_conn_params_init(&amp;amp;cp_init);
	APP_ERROR_CHECK(err_code);
}

/**
 * @brief Function for putting the chip into sleep mode.
 *
 * @note This function does not return.
 */
static void sleep_mode_enter(void)
{
	uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
	APP_ERROR_CHECK(err_code);

	// Prepare wakeup buttons.
	err_code = bsp_btn_ble_sleep_mode_prepare();
	APP_ERROR_CHECK(err_code);

	// Go to system-off mode (this function will not return; wakeup will cause a reset).
	err_code = sd_power_system_off();
	APP_ERROR_CHECK(err_code);
}

/** @brief Function for starting advertising. */
static void advertising_start(void)
{
	uint32_t err_code = ble_advertising_start(&amp;amp;m_advertising, BLE_ADV_MODE_FAST);
	APP_ERROR_CHECK(err_code);
}

/**
 * @brief Function for handling advertising events.
 *
 * @details This function is called for advertising events which are passed to the application.
 *
 * @param[in] ble_adv_evt  Advertising event.
 */
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
	uint32_t err_code;

	switch (ble_adv_evt) {
	case BLE_ADV_EVT_FAST:
		err_code = app_timer_start(m_blink_ble,
		    APP_TIMER_TICKS(LED_BLINK_INTERVAL),
		    (void *)LED_BLE_NUS_CONN);
		APP_ERROR_CHECK(err_code);
		break;
	case BLE_ADV_EVT_IDLE:
		NRF_LOG_INFO(&amp;quot;Advertising timeout, restarting.&amp;quot;)
		advertising_start();
		break;
	default:
		break;
	}
}

/**
 * @brief Function for handling BLE events.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 * @param[in]   p_context   Unused.
 */
static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
{
	uint32_t err_code;

	switch (p_ble_evt-&amp;gt;header.evt_id) {
	case BLE_GAP_EVT_CONNECTED:
		NRF_LOG_INFO(&amp;quot;BLE NUS connected&amp;quot;);
		err_code = app_timer_stop(m_blink_ble);
		APP_ERROR_CHECK(err_code);
		bsp_board_led_on(LED_BLE_NUS_CONN);
		m_conn_handle = p_ble_evt-&amp;gt;evt.gap_evt.conn_handle;
		break;

	case BLE_GAP_EVT_DISCONNECTED:
		NRF_LOG_INFO(&amp;quot;BLE NUS disconnected&amp;quot;);
		// LED indication will be changed when advertising starts.
		m_conn_handle = BLE_CONN_HANDLE_INVALID;
		break;

	case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
		NRF_LOG_DEBUG(&amp;quot;PHY update request.&amp;quot;);
		ble_gap_phys_t const phys =
		    {
			.rx_phys = BLE_GAP_PHY_AUTO,
			.tx_phys = BLE_GAP_PHY_AUTO,
		    };
		err_code = sd_ble_gap_phy_update(p_ble_evt-&amp;gt;evt.gap_evt.conn_handle, &amp;amp;phys);
		APP_ERROR_CHECK(err_code);
	} break;

	case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
		// Pairing not supported.
		err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
		APP_ERROR_CHECK(err_code);
		break;

	case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: {
		ble_gap_data_length_params_t dl_params;

		// Clearing the struct will effectively set members to @ref BLE_GAP_DATA_LENGTH_AUTO.
		memset(&amp;amp;dl_params, 0, sizeof(ble_gap_data_length_params_t));
		err_code = sd_ble_gap_data_length_update(p_ble_evt-&amp;gt;evt.gap_evt.conn_handle, &amp;amp;dl_params, NULL);
		APP_ERROR_CHECK(err_code);
	} break;

	case BLE_GATTS_EVT_SYS_ATTR_MISSING:
		// No system attributes have been stored.
		err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
		APP_ERROR_CHECK(err_code);
		break;

	case BLE_GATTC_EVT_TIMEOUT:
		// Disconnect on GATT Client timeout event.
		err_code = sd_ble_gap_disconnect(p_ble_evt-&amp;gt;evt.gattc_evt.conn_handle,
		    BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
		APP_ERROR_CHECK(err_code);
		break;

	case BLE_GATTS_EVT_TIMEOUT:
		// Disconnect on GATT Server timeout event.
		err_code = sd_ble_gap_disconnect(p_ble_evt-&amp;gt;evt.gatts_evt.conn_handle,
		    BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
		APP_ERROR_CHECK(err_code);
		break;

	case BLE_EVT_USER_MEM_REQUEST:
		err_code = sd_ble_user_mem_reply(p_ble_evt-&amp;gt;evt.gattc_evt.conn_handle, NULL);
		APP_ERROR_CHECK(err_code);
		break;

	case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: {
		ble_gatts_evt_rw_authorize_request_t req;
		ble_gatts_rw_authorize_reply_params_t auth_reply;

		req = p_ble_evt-&amp;gt;evt.gatts_evt.params.authorize_request;

		if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) {
			if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) ||
			    (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
			    (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) {
				if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) {
					auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
				} else {
					auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
				}
				auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
				err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt-&amp;gt;evt.gatts_evt.conn_handle,
				    &amp;amp;auth_reply);
				APP_ERROR_CHECK(err_code);
			}
		}
	} break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST

	default:
		// No implementation needed.
		break;
	}
}

/**
 * @brief Function for the SoftDevice initialization.
 *
 * @details This function initializes the SoftDevice and the BLE event interrupt.
 */
static void ble_stack_init(void)
{
	ret_code_t err_code;

	err_code = nrf_sdh_enable_request();
	APP_ERROR_CHECK(err_code);

	// Configure the BLE stack using the default settings.
	// Fetch the start address of the application RAM.
	uint32_t ram_start = 0;
	err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &amp;amp;ram_start);
	APP_ERROR_CHECK(err_code);

	// Enable BLE stack.
	err_code = nrf_sdh_ble_enable(&amp;amp;ram_start);
	APP_ERROR_CHECK(err_code);

	// Register a handler for BLE events.
	NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}

/** @brief Function for handling events from the GATT library. */
void gatt_evt_handler(nrf_ble_gatt_t *p_gatt, nrf_ble_gatt_evt_t const *p_evt)
{
	if ((m_conn_handle == p_evt-&amp;gt;conn_handle) &amp;amp;&amp;amp; (p_evt-&amp;gt;evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) {
		m_ble_nus_max_data_len = p_evt-&amp;gt;params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
		NRF_LOG_INFO(&amp;quot;Data len is set to 0x%X(%d)&amp;quot;, m_ble_nus_max_data_len, m_ble_nus_max_data_len);
	}
	NRF_LOG_DEBUG(&amp;quot;ATT MTU exchange completed. central 0x%x peripheral 0x%x&amp;quot;,
	    p_gatt-&amp;gt;att_mtu_desired_central,
	    p_gatt-&amp;gt;att_mtu_desired_periph);
}

/** @brief Function for initializing the GATT library. */
void gatt_init(void)
{
	ret_code_t err_code;

	err_code = nrf_ble_gatt_init(&amp;amp;m_gatt, gatt_evt_handler);
	APP_ERROR_CHECK(err_code);

	err_code = nrf_ble_gatt_att_mtu_periph_set(&amp;amp;m_gatt, 64);
	APP_ERROR_CHECK(err_code);
}

/**
 * @brief Function for handling events from the BSP module.
 *
 * @param[in]   event   Event generated by button press.
 */
void bsp_event_handler(bsp_event_t event)
{
	uint32_t err_code;
	switch (event) {
	case BSP_EVENT_SLEEP:
		sleep_mode_enter();
		break;

	case BSP_EVENT_DISCONNECT:
		err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
		if (err_code != NRF_ERROR_INVALID_STATE) {
			APP_ERROR_CHECK(err_code);
		}
		break;

	case BSP_EVENT_WHITELIST_OFF:
		if (m_conn_handle == BLE_CONN_HANDLE_INVALID) {
			err_code = ble_advertising_restart_without_whitelist(&amp;amp;m_advertising);
			if (err_code != NRF_ERROR_INVALID_STATE) {
				APP_ERROR_CHECK(err_code);
			}
		}
		break;

	default:
		break;
	}
}

/** @brief Function for initializing the Advertising functionality. */
static void advertising_init(void)
{
	uint32_t err_code;
	ble_advertising_init_t init;

	memset(&amp;amp;init, 0, sizeof(init));

	init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
	init.advdata.include_appearance = false;
	init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;

	init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
	init.srdata.uuids_complete.p_uuids = m_adv_uuids;

	init.config.ble_adv_fast_enabled = true;
	init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
	init.config.ble_adv_fast_timeout = APP_ADV_DURATION;

	init.evt_handler = on_adv_evt;

	err_code = ble_advertising_init(&amp;amp;m_advertising, &amp;amp;init);
	APP_ERROR_CHECK(err_code);

	ble_advertising_conn_cfg_tag_set(&amp;amp;m_advertising, APP_BLE_CONN_CFG_TAG);
}

/** @brief Function for initializing buttons and LEDs. */
static void buttons_leds_init(void)
{
	uint32_t err_code = bsp_init(BSP_INIT_LEDS, bsp_event_handler);
	APP_ERROR_CHECK(err_code);
}

/** @brief Function for initializing the nrf_log module. */
static void log_init(void)
{
	ret_code_t err_code = NRF_LOG_INIT(NULL);
	APP_ERROR_CHECK(err_code);

	NRF_LOG_DEFAULT_BACKENDS_INIT();
}

/** @brief Function for placing the application in low power state while waiting for events. */
static void power_manage(void)
{
	uint32_t err_code = sd_app_evt_wait();
	APP_ERROR_CHECK(err_code);
}

/**
 * @brief Function for handling the idle state (main loop).
 *
 * @details If there is no pending log operation, then sleep until next the next event occurs.
 */
static void idle_state_handle(void)
{
	UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
	power_manage();
}

// USB CODE START
static bool m_usb_connected = false;

/** @brief User event handler @ref app_usbd_cdc_acm_user_ev_handler_t */
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const *p_inst,
    app_usbd_cdc_acm_user_event_t event)
{
	app_usbd_cdc_acm_t const *p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);

	switch (event) {
	case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN: {
		/*Set up the first transfer*/
		ret_code_t ret = app_usbd_cdc_acm_read(&amp;amp;m_app_cdc_acm,
		    m_cdc_data_array,
		    1);
		UNUSED_VARIABLE(ret);
		ret = app_timer_stop(m_blink_cdc);
		APP_ERROR_CHECK(ret);
		bsp_board_led_on(LED_CDC_ACM_CONN);
		NRF_LOG_INFO(&amp;quot;CDC ACM port opened&amp;quot;);
		break;
	}

	case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
		NRF_LOG_INFO(&amp;quot;CDC ACM port closed&amp;quot;);
		if (m_usb_connected) {
			ret_code_t ret = app_timer_start(m_blink_cdc,
			    APP_TIMER_TICKS(LED_BLINK_INTERVAL),
			    (void *)LED_CDC_ACM_CONN);
			APP_ERROR_CHECK(ret);
		}
		break;

	case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
		break;

	case APP_USBD_CDC_ACM_USER_EVT_RX_DONE: {
		ret_code_t ret;
		static uint8_t index = 0;
		index++;

		do {
			if ((m_cdc_data_array[index - 1] == &amp;#39;\n&amp;#39;) ||
			    (m_cdc_data_array[index - 1] == &amp;#39;\r&amp;#39;) ||
			    (index &amp;gt;= (m_ble_nus_max_data_len))) {
				if (index &amp;gt; 1) {
					bsp_board_led_invert(LED_CDC_ACM_RX);
					NRF_LOG_DEBUG(&amp;quot;Ready to send data over BLE NUS&amp;quot;);
					NRF_LOG_HEXDUMP_DEBUG(m_cdc_data_array, index);

					do {
						uint16_t length = (uint16_t)index;
						if (length + sizeof(ENDLINE_STRING) &amp;lt; BLE_NUS_MAX_DATA_LEN) {
							memcpy(m_cdc_data_array + length, ENDLINE_STRING, sizeof(ENDLINE_STRING));
							length += sizeof(ENDLINE_STRING);
						}

						ret = ble_nus_data_send(&amp;amp;m_nus,
						    (uint8_t *)m_cdc_data_array,
						    &amp;amp;length,
						    m_conn_handle);

						if (ret == NRF_ERROR_NOT_FOUND) {
							NRF_LOG_INFO(&amp;quot;BLE NUS unavailable, data received: %s&amp;quot;, m_cdc_data_array);
							break;
						}

						if (ret == NRF_ERROR_RESOURCES) {
							NRF_LOG_ERROR(&amp;quot;BLE NUS Too many notifications queued.&amp;quot;);
							break;
						}

						if ((ret != NRF_ERROR_INVALID_STATE) &amp;amp;&amp;amp; (ret != NRF_ERROR_BUSY)) {
							APP_ERROR_CHECK(ret);
						}
					} while (ret == NRF_ERROR_BUSY);
				}

				index = 0;
			}

			/*Get amount of data transferred*/
			size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
			NRF_LOG_DEBUG(&amp;quot;RX: size: %lu char: %c&amp;quot;, size, m_cdc_data_array[index - 1]);

			/* Fetch data until internal buffer is empty */
			ret = app_usbd_cdc_acm_read(&amp;amp;m_app_cdc_acm,
			    &amp;amp;m_cdc_data_array[index],
			    1);
			if (ret == NRF_SUCCESS) {
				index++;
			}
		} while (ret == NRF_SUCCESS);

		NRF_LOG_HEXDUMP_INFO(m_cdc_data_array, index);
		break;
	}
	default:
		break;
	}
}

static void usbd_user_ev_handler(app_usbd_event_type_t event)
{
	switch (event) {
	case APP_USBD_EVT_DRV_SUSPEND:
		break;

	case APP_USBD_EVT_DRV_RESUME:
		break;

	case APP_USBD_EVT_STARTED:
		break;

	case APP_USBD_EVT_STOPPED:
		app_usbd_disable();
		break;

	case APP_USBD_EVT_POWER_DETECTED:
		NRF_LOG_INFO(&amp;quot;USB power detected&amp;quot;);

		if (!nrf_drv_usbd_is_enabled()) {
			app_usbd_enable();
		}
		break;

	case APP_USBD_EVT_POWER_REMOVED: {
		NRF_LOG_INFO(&amp;quot;USB power removed&amp;quot;);
		ret_code_t err_code = app_timer_stop(m_blink_cdc);
		APP_ERROR_CHECK(err_code);
		bsp_board_led_off(LED_CDC_ACM_CONN);
		m_usb_connected = false;
		app_usbd_stop();
	} break;

	case APP_USBD_EVT_POWER_READY: {
		NRF_LOG_INFO(&amp;quot;USB ready&amp;quot;);
		ret_code_t err_code = app_timer_start(m_blink_cdc,
		    APP_TIMER_TICKS(LED_BLINK_INTERVAL),
		    (void *)LED_CDC_ACM_CONN);
		APP_ERROR_CHECK(err_code);
		m_usb_connected = true;
		app_usbd_start();
	} break;

	default:
		break;
	}
}

// USB CODE END

/** @brief Application main function. */
int main(void)
{
	ret_code_t ret;
	static const app_usbd_config_t usbd_config = {
	    .ev_state_proc = usbd_user_ev_handler};
	// Initialize.
	log_init();
	timers_init();

	buttons_leds_init();

	app_usbd_serial_num_generate();

	ret = nrf_drv_clock_init();
	APP_ERROR_CHECK(ret);

	NRF_LOG_INFO(&amp;quot;USBD BLE UART example started.&amp;quot;);

	ret = app_usbd_init(&amp;amp;usbd_config);
	APP_ERROR_CHECK(ret);

	app_usbd_class_inst_t const *class_cdc_acm = app_usbd_cdc_acm_class_inst_get(&amp;amp;m_app_cdc_acm);
	ret = app_usbd_class_append(class_cdc_acm);
	APP_ERROR_CHECK(ret);

	ble_stack_init();
	gap_params_init();
	gatt_init();
	services_init();
	advertising_init();
	conn_params_init();

	// Start execution.
	advertising_start();

	ret = app_usbd_power_events_enable();
	APP_ERROR_CHECK(ret);

	// Enter main loop.
	for (;;) {
		while (app_usbd_event_queue_process()) {

			
			/* Nothing to do */
		}

		idle_state_handle();
	}
}

/**
 * @}
 */&lt;/pre&gt;main code is attached as well&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>