<?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>Connect to two peripheral devices at once using nRF52 dongle</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/46093/connect-to-two-peripheral-devices-at-once-using-nrf52-dongle</link><description>Hello, 
 
 We are using PCA10059 with the pc-ble-driver as a central to connect to our device, which is based on the nRF52832. 
 
 We need to be able to connect to two peripheral devices at once. 
 However, the default softdevice (v3) doesn&amp;#39;t seem to</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 30 Apr 2019 08:49:30 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/46093/connect-to-two-peripheral-devices-at-once-using-nrf52-dongle" /><item><title>RE: Connect to two peripheral devices at once using nRF52 dongle</title><link>https://devzone.nordicsemi.com/thread/184482?ContentTypeID=1</link><pubDate>Tue, 30 Apr 2019 08:49:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:590e20a6-be02-4daa-bce4-f5a3cb3e4276</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;You need to increase&amp;nbsp;central_conn_count,&amp;nbsp;&lt;span&gt;periph_conn_count configures how many connections&amp;nbsp;&lt;em&gt;&lt;strong&gt;as a peripheral&lt;/strong&gt;&lt;/em&gt;&lt;strong&gt;&lt;/strong&gt; the softdevice can support. I sd_api_v3 this is limited to 1.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Connect to two peripheral devices at once using nRF52 dongle</title><link>https://devzone.nordicsemi.com/thread/182349?ContentTypeID=1</link><pubDate>Tue, 16 Apr 2019 11:33:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f11e5d9a-e420-4adf-b931-789d14137c5b</guid><dc:creator>Liav Adi</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;I am using sd_api_3.&amp;nbsp;I have 2 devices which I collect when receiving&amp;nbsp;BLE_GAP_EVT_ADV_REPORT.&lt;/p&gt;
&lt;p&gt;Then, I try to connect to both. The first one went well.&amp;nbsp; It is connected, found its services, characteristics, descriptors, and then getting the data. Then, and only when I am getting the data, I tries to connect to the second one, and I get :&amp;nbsp;&lt;br /&gt;Connection Request Failed, reason 18 (NRF_ERROR_CONN_COUNT) .&lt;/p&gt;
&lt;p&gt;I tried to change&amp;nbsp;ble_enable_params.gap_enable_params.periph_conn_count = 1,&lt;/p&gt;
&lt;p&gt;from 1 to 2.&lt;/p&gt;
&lt;p&gt;But then for the&amp;nbsp;sd_ble_enable(m_adapter, &amp;amp;ble_enable_params, app_ram_base)&lt;/p&gt;
&lt;p&gt;I get again error 18.&lt;/p&gt;
&lt;p&gt;Maybe after all&amp;nbsp;&amp;nbsp;&lt;span&gt;sd_api_3 doesn&amp;#39;t support multi devices ?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;In addition, I also found out that if I do not call connect device the same thread of the Dispatch function it doesn&amp;#39;t&amp;nbsp;work. And&amp;nbsp;that is true also fro one connection.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I&lt;pre class="ui-code" data-mode="text"&gt;#include &amp;quot;stdafx.h&amp;quot;
#include &amp;quot;BleManager.h&amp;quot;
#include &amp;quot;BleDevice.h&amp;quot;

using namespace Mudra::Ble::Windows::NordicExternal;
using namespace Mudra::Ble;
using namespace std;
using namespace Mudra::Computation;

#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME)*1000) / (RESOLUTION))
#define MIN_CONNECTION_INTERVAL    MSEC_TO_UNITS(7.5, UNIT_1_25_MS) 
#define MAX_CONNECTION_INTERVAL    MSEC_TO_UNITS(7.5, UNIT_1_25_MS)
#define SLAVE_LATENCY 0
#define CONNECTION_SUPERVISION_TIMEOUT MSEC_TO_UNITS(20000, UNIT_10_MS)

adapter_t* m_adapter = NULL;
static uint16_t m_service_start_handle = 0;
static uint16_t m_service_end_handle = 0;
static uint16_t m_SNC_char_start_handle = 0;
static uint16_t m_IMU_char_start_handle = 0;
static uint16_t m_cccd_handle = 0;
static shared_ptr&amp;lt;Logger&amp;gt; m_logger;
std::map&amp;lt;HandleType, shared_ptr&amp;lt;BleDevice&amp;gt;&amp;gt; m_devices;
shared_ptr&amp;lt;BleDevice&amp;gt; m_connectedDevice;
std::vector&amp;lt;std::string&amp;gt; m_advDevices;

static Mudra::Ble::OnSncDataReadyCallbackType m_onSncDataReadyCallback = nullptr;
static Mudra::Ble::OnImuDataReadyCallbackType m_onImuDataReadyCallback = nullptr;
static Mudra::Ble::OnDeviceDiscoveredCallbackType m_onDeviceDiscoveredCallback = nullptr;

const unsigned STRING_BUFFER_SIZE = 50;
const int DEFAULT_BAUD_RATE = 1000000; /**&amp;lt; The baud rate to be used for serial communication with nRF5 device. */
const int GATT_MUDRA_SIZE = 247; /**&amp;lt; The baud rate to be used for serial communication with nRF5 device. */

const uint16_t SCAN_INTERVAL = 0x00A0; /**&amp;lt; Determines scan interval in units of 0.625 milliseconds. */
const uint16_t SCAN_WINDOW = 0x0050;   /**&amp;lt; Determines scan window in units of 0.625 milliseconds. */
const uint16_t SCAN_TIMEOUT = 0x05;	/**&amp;lt; Scan timeout between 0x01 and 0xFFFF in seconds, 0x0 disables timeout. */

const uint16_t  MUDRA_DATA_SERVICE_UUID = 0xfff0;
const uint16_t  SNC_CHARACT_UUID = 0xfff4;
const uint16_t  IMU_CHARACT_UUID = 0xfff5;
const uint16_t  BLE_UUID_CCCD = 0x2902;
const uint16_t  BLE_CCCD_NOTIFY = 0x01;

const ble_gap_scan_params_t m_scanParam = {
   0, // Set if active scanning.
   0, // Set if selective scanning.
   0, // Set adv_dir_report.
   SCAN_INTERVAL,
   SCAN_WINDOW,
   SCAN_TIMEOUT
};

typedef struct
{
	uint8_t* p_data;   /**&amp;lt; Pointer to data. */
	uint16_t data_len; /**&amp;lt; Length of data. */
} data_t;

enum {
	UNIT_0_625_MS = 625,  /**&amp;lt; Number of microseconds in 0.625 milliseconds. */
	UNIT_1_25_MS = 1250, /**&amp;lt; Number of microseconds in 1.25 milliseconds. */
	UNIT_10_MS = 10000 /**&amp;lt; Number of microseconds in 10 milliseconds. */
};

enum State {
	None,
	SettingSncDescriprors,
	SettingImuDescriprors,
};

State m_state = State::None;


static const ble_gap_conn_params_t m_connection_param = {
	(uint16_t)MIN_CONNECTION_INTERVAL, (uint16_t)MAX_CONNECTION_INTERVAL, (uint16_t)SLAVE_LATENCY,
	(uint16_t)CONNECTION_SUPERVISION_TIMEOUT };

static adapter_t* AdapterInit(const char* serial_port, uint32_t baud_rate);
static uint32_t StackInit();
static uint32_t OptionsSet();
static uint32_t ScanStart();
static void Dispatch(adapter_t* adapter, ble_evt_t* p_ble_evt);
static bool ServiceDiscoveryStart();
static void OnServiceDiscoveryResponse(const ble_gattc_evt_t* const p_ble_gattc_evt);
static uint32_t CharDiscoveryStart();
static void OnCharacteristicDiscoveryResponse(const ble_gattc_evt_t* const p_ble_gattc_evt);
static uint32_t DescrDiscoveryStart(uint16_t charStartHandle);
static void OnDescriptorDiscoveryResponse(const ble_gattc_evt_t* const p_ble_gattc_evt);
static uint32_t SetNotify(uint16_t handle);

static void ble_address_to_string_convert(ble_gap_addr_t address, char* string_buffer)
{
	const int address_length = 6;
	char temp_str[3];

	for (int i = address_length - 1; i &amp;gt;= 0; --i)
	{
		sprintf(temp_str, &amp;quot;%02X&amp;quot;, address.addr[i]);
		strcat((char*)string_buffer, temp_str);
	}
}

static uint32_t adv_report_parse(uint8_t type, data_t* p_advdata, data_t* p_typedata)
{
	uint32_t index = 0;
	uint8_t* p_data;

	p_data = p_advdata-&amp;gt;p_data;

	while (index &amp;lt; p_advdata-&amp;gt;data_len)
	{
		uint8_t field_length = p_data[index];
		uint8_t field_type = p_data[index + 1];

		if (field_type == type)
		{
			p_typedata-&amp;gt;p_data = &amp;amp;p_data[index + 2];
			p_typedata-&amp;gt;data_len = field_length - 1;
			return NRF_SUCCESS;
		}
		index += field_length + 1;
	}
	return NRF_ERROR_NOT_FOUND;
}


static bool find_adv_name(const ble_gap_evt_adv_report_t* p_adv_report, const char* name_to_find)
{
	data_t adv_data;
	data_t dev_name;

	adv_data.p_data = (uint8_t*)p_adv_report-&amp;gt;data;
	adv_data.data_len = p_adv_report-&amp;gt;dlen;

	auto err_code = adv_report_parse(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, &amp;amp;adv_data, &amp;amp;dev_name);
	if (err_code == NRF_SUCCESS)
	{
		return (memcmp(name_to_find, dev_name.p_data, dev_name.data_len) == 0);
	}

	return false;
}

void OnAdvReport(const ble_gap_evt_t * const p_ble_gap_evt)
{
	char str[STRING_BUFFER_SIZE] = { 0 };

	// Log the Blue tooth device address of advertisement packet received.
	ble_address_to_string_convert(p_ble_gap_evt-&amp;gt;params.adv_report.peer_addr, str);
	printf(&amp;quot;.&amp;quot;);

	fflush(stdout);

	if (strcmp(str, &amp;quot;CA62BA4C71E3&amp;quot;) != 0 &amp;amp;&amp;amp;
		strcmp(str, &amp;quot;CF6C069FC6D2&amp;quot;) != 0)
	{
		return;
	}


	if (find_adv_name(&amp;amp;p_ble_gap_evt-&amp;gt;params.adv_report, &amp;quot;WLD Mudra&amp;quot;))
	{
		bool found = std::find(m_advDevices.begin(), m_advDevices.end(), str) != m_advDevices.end();

		if (!found)
		{
			m_advDevices.push_back(str);
			auto d = make_shared&amp;lt;BleDevice&amp;gt;(&amp;amp;(p_ble_gap_evt-&amp;gt;params.adv_report.peer_addr), std::string(str));
			printf(&amp;quot;\nReceived advertisement report with device address: 0x%s&amp;quot;, str);
			m_onDeviceDiscoveredCallback(d);
		}
	}
}

static void OnTimeout(const ble_gap_evt_t * const p_ble_gap_evt)
{
	if (p_ble_gap_evt-&amp;gt;params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
	{
		m_connectedDevice = nullptr;
	}
	else if (p_ble_gap_evt-&amp;gt;params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN)
	{
		ScanStart();
	}
}



static void OnConnected(const ble_gap_evt_t * const p_ble_gap_evt)
{
	printf(&amp;quot;\nConnection established\n&amp;quot;);
	fflush(stdout);

	m_connectedDevice-&amp;gt;SetConnectionHandle(p_ble_gap_evt-&amp;gt;conn_handle);

	m_devices[p_ble_gap_evt-&amp;gt;conn_handle] = m_connectedDevice;

	ServiceDiscoveryStart();
}

static bool ServiceDiscoveryStart()
{
	uint32_t err_code;
	uint16_t start_handle = 20;
	ble_uuid_t srvc_uuid;

	srvc_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN;

	ble_uuid128_t srvc_128_uuid = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
								   0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

	err_code = sd_ble_uuid_vs_add(m_adapter, &amp;amp;srvc_128_uuid, &amp;amp;srvc_uuid.type);

	if (err_code != NRF_SUCCESS)
	{
		printf(&amp;quot;Failed to add the Mudra service.\n&amp;quot;);
		fflush(stdout);
		return false;
	}

	printf(&amp;quot;Discovering primary services\n&amp;quot;);
	fflush(stdout);

	err_code =
		sd_ble_gattc_primary_services_discover(m_adapter, m_connectedDevice-&amp;gt;GetConnectionHandle(), start_handle, NULL);

	return true;
}

static void OnServiceDiscoveryResponse(const ble_gattc_evt_t * const p_ble_gattc_evt)
{
	int count;
	const ble_gattc_service_t* service;

	printf(&amp;quot;Received service discovery response\n&amp;quot;);
	fflush(stdout);

	if (p_ble_gattc_evt-&amp;gt;gatt_status != NRF_SUCCESS)
	{
		printf(&amp;quot;Service discovery failed. Error code 0x%X\n&amp;quot;, p_ble_gattc_evt-&amp;gt;gatt_status);
		fflush(stdout);
		return;
	}

	count = p_ble_gattc_evt-&amp;gt;params.prim_srvc_disc_rsp.count;

	if (count == 0)
	{
		printf(&amp;quot;Service not found\n&amp;quot;);
		fflush(stdout);
		return;
	}

	for (int service_index = 0; service_index &amp;lt; count; service_index++)
	{
		service = &amp;amp;(p_ble_gattc_evt-&amp;gt;params.prim_srvc_disc_rsp.services[service_index]);

		if (service-&amp;gt;uuid.uuid == MUDRA_DATA_SERVICE_UUID)
		{
			m_service_start_handle = service-&amp;gt;handle_range.start_handle;
			m_service_end_handle = service-&amp;gt;handle_range.end_handle;

			printf(&amp;quot;Found Mudra data service start=0x%04X end=0x%04X\n&amp;quot;, m_service_start_handle, m_service_end_handle);
			fflush(stdout);

			CharDiscoveryStart();
		}
	}
}

static uint32_t CharDiscoveryStart()
{
	ble_gattc_handle_range_t handle_range;

	printf(&amp;quot;Discovering characteristics\n&amp;quot;);
	fflush(stdout);

	handle_range.start_handle = m_service_start_handle;
	handle_range.end_handle = m_service_end_handle;

	return sd_ble_gattc_characteristics_discover(m_adapter, m_connectedDevice-&amp;gt;GetConnectionHandle(), &amp;amp;handle_range);
}

static uint32_t DescrDiscoveryStart(uint16_t charStartHandle)
{
	ble_gattc_handle_range_t handle_range;

	printf(&amp;quot;Discovering characteristic&amp;#39;s descriptors  0x%04X -  0x%04X\n&amp;quot;, charStartHandle,
		charStartHandle + 2);
	fflush(stdout);

	if (charStartHandle == 0)
	{
		printf(&amp;quot;No heart rate measurement characteristic handle found\n&amp;quot;);
		fflush(stdout);
		return NRF_ERROR_INVALID_STATE;
	}

	handle_range.start_handle = charStartHandle;
	handle_range.end_handle = charStartHandle + 2;

	return sd_ble_gattc_descriptors_discover(m_adapter, m_connectedDevice-&amp;gt;GetConnectionHandle(), &amp;amp;handle_range);
}

static void OnCharacteristicDiscoveryResponse(const ble_gattc_evt_t * const p_ble_gattc_evt)
{
	int count = p_ble_gattc_evt-&amp;gt;params.char_disc_rsp.count;

	if (p_ble_gattc_evt-&amp;gt;gatt_status != NRF_SUCCESS)
	{
		printf(&amp;quot;Characteristic discovery failed. Error code 0x%X\n&amp;quot;, p_ble_gattc_evt-&amp;gt;gatt_status);
		fflush(stdout);
		return;
	}

	printf(&amp;quot;Received characteristic discovery resp , characteristics count: %d\n&amp;quot;, count);
	fflush(stdout);

	for (int i = 0; i &amp;lt; count; i++)
	{
		printf(&amp;quot;Characteristic handle: 0x%04X, UUID: 0x%04X&amp;quot;,
			p_ble_gattc_evt-&amp;gt;params.char_disc_rsp.chars[i].handle_decl,
			p_ble_gattc_evt-&amp;gt;params.char_disc_rsp.chars[i].uuid.uuid);
		fflush(stdout);

		switch (p_ble_gattc_evt-&amp;gt;params.char_disc_rsp.chars[i].uuid.uuid)
		{
		case SNC_CHARACT_UUID:
			printf(&amp;quot; SNC char&amp;quot;);
			fflush(stdout);
			m_state = SettingSncDescriprors;
			m_SNC_char_start_handle = p_ble_gattc_evt-&amp;gt;params.char_disc_rsp.chars[i].handle_decl;
			break;
		case IMU_CHARACT_UUID:
			printf(&amp;quot; IMU char&amp;quot;);
			fflush(stdout);
			m_IMU_char_start_handle = p_ble_gattc_evt-&amp;gt;params.char_disc_rsp.chars[i].handle_decl;
			break;
		}
		printf(&amp;quot;\n&amp;quot;);
		fflush(stdout);
	}
	DescrDiscoveryStart(m_SNC_char_start_handle);
}

static void OnDescriptorDiscoveryResponse(const ble_gattc_evt_t * const p_ble_gattc_evt)
{
	int count = p_ble_gattc_evt-&amp;gt;params.desc_disc_rsp.count;

	if (p_ble_gattc_evt-&amp;gt;gatt_status != NRF_SUCCESS)
	{
		printf(&amp;quot;Descriptor discovery failed. Error code 0x%X\n&amp;quot;, p_ble_gattc_evt-&amp;gt;gatt_status);
		fflush(stdout);
		return;
	}

	printf(&amp;quot;Received descriptor discovery response, descriptor count: %d\n&amp;quot;, count);
	fflush(stdout);

	for (int i = 0; i &amp;lt; count; i++)
	{
		printf(&amp;quot;Descriptor handle: 0x%04X, UUID: 0x%04X\n&amp;quot;,
			p_ble_gattc_evt-&amp;gt;params.desc_disc_rsp.descs[i].handle,
			p_ble_gattc_evt-&amp;gt;params.desc_disc_rsp.descs[i].uuid.uuid);
		fflush(stdout);

		if (p_ble_gattc_evt-&amp;gt;params.desc_disc_rsp.descs[i].uuid.uuid == BLE_UUID_CCCD)
		{
			m_cccd_handle = p_ble_gattc_evt-&amp;gt;params.desc_disc_rsp.descs[i].handle;
			printf(&amp;quot;Set notify to 0x%04X\n&amp;quot;, m_cccd_handle);
			fflush(stdout);

			SetNotify(m_cccd_handle);
		}
	}
}

static uint32_t SetNotify(uint16_t handle)
{
	uint8_t value = 0;
	value ^= BLE_CCCD_NOTIFY;

	ble_gattc_write_params_t write_params;
	uint8_t cccd_value[2] = { value, 0 };

	printf(&amp;quot;Setting notify CCCD\n&amp;quot;);
	fflush(stdout);

	if (m_cccd_handle == 0)
	{
		printf(&amp;quot;Error. No CCCD handle has been found\n&amp;quot;);
		fflush(stdout);
		return NRF_ERROR_INVALID_STATE;
	}

	write_params.handle = handle;
	write_params.len = 2;
	write_params.p_value = cccd_value;
	write_params.write_op = BLE_GATT_OP_WRITE_REQ;
	write_params.offset = 0;

	return sd_ble_gattc_write(m_adapter, m_connectedDevice-&amp;gt;GetConnectionHandle(), &amp;amp;write_params);
}

static void on_write_response(const ble_gattc_evt_t * const p_ble_gattc_evt)
{
	printf(&amp;quot;Received write response 0x%04X\n&amp;quot;, p_ble_gattc_evt-&amp;gt;params.write_rsp.handle);
	fflush(stdout);

	if (p_ble_gattc_evt-&amp;gt;gatt_status != NRF_SUCCESS)
	{
		printf(&amp;quot;Error. Write operation failed. Error code 0x%X\n&amp;quot;, p_ble_gattc_evt-&amp;gt;gatt_status);
		fflush(stdout);
	}

	switch (m_state)
	{
	case State::SettingSncDescriprors:
		m_state = SettingImuDescriprors;
		DescrDiscoveryStart(m_IMU_char_start_handle);
		break;
	case State::SettingImuDescriprors:
		m_state = State::None;
		m_connectedDevice = nullptr;
		break;
	}
}

enum class DataType
{
	None,
	SncRecieved,
	ImuRecieved
};

static void on_hvx(const ble_gattc_evt_t * const p_ble_gattc_evt)
{
	auto&amp;amp; handle = p_ble_gattc_evt-&amp;gt;params.hvx.handle;
	auto&amp;amp; connectionHandle = p_ble_gattc_evt-&amp;gt;conn_handle;

	DataType dataType = DataType::None;
	BufferType buffer;

	//    printf(&amp;quot;0x%04X &amp;quot;, p_ble_gattc_evt-&amp;gt;params.hvx.handle);
	if (handle &amp;gt;= m_SNC_char_start_handle &amp;amp;&amp;amp; handle &amp;lt;= m_SNC_char_start_handle + 2) // Heart rate measurement.
	{
		//		DebugMessage(m_logger) &amp;lt;&amp;lt; &amp;quot;\nReceived SNC data, size=&amp;quot; &amp;lt;&amp;lt; p_ble_gattc_evt-&amp;gt;params.hvx.len;
		dataType = DataType::SncRecieved;
	}
	else if (handle &amp;gt;= m_IMU_char_start_handle &amp;amp;&amp;amp; handle &amp;lt;= m_IMU_char_start_handle + 2) // Heart rate measurement.
	{
		//		DebugMessage(m_logger) &amp;lt;&amp;lt; &amp;quot;\nReceived IMU data, size=&amp;quot; &amp;lt;&amp;lt; p_ble_gattc_evt-&amp;gt;params.hvx.len;
		dataType = DataType::ImuRecieved;
	}

	if (dataType != DataType::None)
	{
		buffer.reserve(p_ble_gattc_evt-&amp;gt;params.hvx.len);
		for (int i = 0; i &amp;lt; p_ble_gattc_evt-&amp;gt;params.hvx.len; i++)
		{
			buffer.push_back(p_ble_gattc_evt-&amp;gt;params.hvx.data[i]);
			//			 
		}
		if (dataType == DataType::SncRecieved &amp;amp;&amp;amp; m_onSncDataReadyCallback)
		{
			m_onSncDataReadyCallback(m_devices[connectionHandle], buffer);
		}
		else if (dataType == DataType::ImuRecieved &amp;amp;&amp;amp; m_onImuDataReadyCallback)
		{
			m_onImuDataReadyCallback(m_devices[connectionHandle], buffer);
		}
		// We know the heart rate reading is encoded as 2 bytes [flag, value].
	}
	else // Unknown data.
	{
		printf(&amp;quot;Un-parsed data received on handle: %04X\n&amp;quot;, handle);
	}

	fflush(stdout);
}

static void on_exchange_mtu_request(const ble_gatts_evt_t * const p_ble_gatts_evt)
{
	printf(&amp;quot;on_exchange_mtu_request\n&amp;quot;);
	fflush(stdout);

	uint32_t err_code = sd_ble_gatts_exchange_mtu_reply(m_adapter, m_connectedDevice-&amp;gt;GetConnectionHandle(), GATT_MUDRA_SIZE);

	if (err_code != NRF_SUCCESS)
	{
		printf(&amp;quot;MTU exchange request reply failed, err_code %d\n&amp;quot;, err_code);
		fflush(stdout);
	}
}


static void Dispatch(adapter_t * adapter, ble_evt_t * p_ble_evt)
{
	if (p_ble_evt == NULL)
	{
		printf(&amp;quot;Received an empty BLE event\n&amp;quot;);
		fflush(stdout);
		return;
	}
	 
	switch (p_ble_evt-&amp;gt;header.evt_id)
	{
	case BLE_GAP_EVT_CONNECTED:
		OnConnected(&amp;amp;(p_ble_evt-&amp;gt;evt.gap_evt));
		break;

	case BLE_GAP_EVT_DISCONNECTED:
		printf(&amp;quot;Disconnected, reason: 0x%02X\n&amp;quot;, p_ble_evt-&amp;gt;evt.gap_evt.params.disconnected.reason);
		fflush(stdout);
		// 		 m_connected_devices--;
		// 		 m_connection_handle = 0;
		break;

	case BLE_GAP_EVT_ADV_REPORT:
		OnAdvReport(&amp;amp;(p_ble_evt-&amp;gt;evt.gap_evt));
		break;

	case BLE_GAP_EVT_TIMEOUT:
		OnTimeout(&amp;amp;(p_ble_evt-&amp;gt;evt.gap_evt));
		break;

	case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
		OnServiceDiscoveryResponse(&amp;amp;(p_ble_evt-&amp;gt;evt.gattc_evt));
		break;

	case BLE_GATTC_EVT_CHAR_DISC_RSP:
		OnCharacteristicDiscoveryResponse(&amp;amp;(p_ble_evt-&amp;gt;evt.gattc_evt));
		break;

	case BLE_GATTC_EVT_DESC_DISC_RSP:
		OnDescriptorDiscoveryResponse(&amp;amp;(p_ble_evt-&amp;gt;evt.gattc_evt));
		break;

	case BLE_GATTC_EVT_WRITE_RSP:
		on_write_response(&amp;amp;(p_ble_evt-&amp;gt;evt.gattc_evt));
		break;

	case BLE_GATTC_EVT_HVX:
		on_hvx(&amp;amp;(p_ble_evt-&amp;gt;evt.gattc_evt));
		break;


	case BLE_GAP_EVT_SEC_REQUEST:
		//		on_conn_params_update_request(&amp;amp;(p_ble_evt-&amp;gt;evt.gap_evt));
		break;

	case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
		//		on_conn_params_update_request(&amp;amp;(p_ble_evt-&amp;gt;evt.gap_evt));
		break;

	case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
		on_exchange_mtu_request(&amp;amp;(p_ble_evt-&amp;gt;evt.gatts_evt));
		break;

	case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
		//		on_exchange_mtu_response(&amp;amp;(p_ble_evt-&amp;gt;evt.gattc_evt));
		break;

	default:
		printf(&amp;quot;Received an un-handled event with ID: %d\n&amp;quot;, p_ble_evt-&amp;gt;header.evt_id);
		fflush(stdout);
		break;
	}
}

/**@brief Function for handling error message events from sd_rpc.
*
* @param[in] adapter The transport adapter.
* @param[in] code Error code that the error message is associated with.
* @param[in] message The error message that the callback is associated with.
*/
static void status_handler(adapter_t * adapter, sd_rpc_app_status_t code, const char* message)
{
	printf(&amp;quot;Status: %d, message: %s\n&amp;quot;, (uint32_t)code, message);
	fflush(stdout);
}

/**@brief Function for handling the log message events from sd_rpc.
*
* @param[in] adapter The transport adapter.
* @param[in] severity Level of severity that the log message is associated with.
* @param[in] message The log message that the callback is associated with.
*/
static void log_handler(adapter_t * adapter, sd_rpc_log_severity_t severity, const char* message)
{
	switch (severity)
	{
	case SD_RPC_LOG_ERROR:
		printf(&amp;quot;Error: %s\n&amp;quot;, message);
		fflush(stdout);
		break;

	case SD_RPC_LOG_WARNING:
		printf(&amp;quot;Warning: %s\n&amp;quot;, message);
		fflush(stdout);
		break;

	case SD_RPC_LOG_INFO:
		printf(&amp;quot;Info: %s\n&amp;quot;, message);
		fflush(stdout);
		break;

	default:
		printf(&amp;quot;Log: %s\n&amp;quot;, message);
		fflush(stdout);
		break;
	}
}

bool scan(const std::string &amp;amp; port)
{
	const char* s = port.c_str();
	m_adapter = AdapterInit(s, DEFAULT_BAUD_RATE);
	sd_rpc_log_handler_severity_filter_set(m_adapter, SD_RPC_LOG_INFO);

	auto error_code = sd_rpc_open(m_adapter, status_handler, Dispatch, log_handler);

	if (error_code != NRF_SUCCESS)
	{
		printf(&amp;quot;Failed to open nRF BLE Driver. Error code: 0x%02X\n&amp;quot;, error_code);
		fflush(stdout);
		return error_code;
	}

	error_code = StackInit();
	if (error_code != NRF_SUCCESS)
	{
		return error_code;
	}

	error_code = OptionsSet();

	if (error_code != NRF_SUCCESS)
	{
		return error_code;
	}

	error_code = ScanStart();

	if (error_code != NRF_SUCCESS)
	{
		return error_code;
	}


	return true;
}

bool connect(std::shared_ptr&amp;lt;IBleDevice&amp;gt; device)
{
	if (m_connectedDevice != nullptr)
	{
		return false;
	}

	m_connectedDevice = dynamic_pointer_cast&amp;lt;BleDevice&amp;gt;(device);

	auto err_code = sd_ble_gap_connect(m_adapter, m_connectedDevice-&amp;gt;GetAddress(), &amp;amp;m_scanParam, &amp;amp;m_connection_param);
	if (err_code != NRF_SUCCESS)
	{
		printf(&amp;quot;\nConnection Request Failed, device %s reason %d&amp;quot;, device-&amp;gt;GetName().c_str(), err_code);
		fflush(stdout);
		return false;
	}

	printf(&amp;quot;\nConnection Request Succeeded, device %s\n&amp;quot;, device-&amp;gt;GetName().c_str());
	fflush(stdout);

	return true;
}

adapter_t* AdapterInit(const char* serial_port, uint32_t baud_rate)
{
	physical_layer_t* phy;
	data_link_layer_t* data_link_layer;
	transport_layer_t* transport_layer;

	phy = sd_rpc_physical_layer_create_uart(serial_port, baud_rate, SD_RPC_FLOW_CONTROL_NONE, SD_RPC_PARITY_NONE);
	data_link_layer = sd_rpc_data_link_layer_create_bt_three_wire(phy, 100);
	transport_layer = sd_rpc_transport_layer_create(data_link_layer, 100);
	return sd_rpc_adapter_create(transport_layer);
}

uint32_t StackInit()
{
	uint32_t err_code;
	uint32_t* app_ram_base = NULL;

	ble_enable_params_t ble_enable_params;
	memset(&amp;amp;ble_enable_params, 0, sizeof(ble_enable_params));

	ble_enable_params.gatt_enable_params.att_mtu = GATT_MUDRA_SIZE;

	ble_enable_params.gap_enable_params.periph_conn_count = 2;
	ble_enable_params.gap_enable_params.central_conn_count = 1;
	ble_enable_params.gap_enable_params.central_sec_count = 1;

	err_code = sd_ble_enable(m_adapter, &amp;amp;ble_enable_params, app_ram_base);

	switch (err_code)
	{
	case NRF_SUCCESS:
		break;
	case NRF_ERROR_INVALID_STATE:
		printf(&amp;quot;BLE stack already enabled\n&amp;quot;);
		fflush(stdout);
		break;
	default:
		printf(&amp;quot;Failed to enable BLE stack. Error code: %d\n&amp;quot;, err_code);
		fflush(stdout);
		break;
	}

	return err_code;
}

uint32_t OptionsSet()
{
	ble_opt_t opt;
	ble_common_opt_t common_opt;

	common_opt.conn_bw.role = BLE_GAP_ROLE_CENTRAL;
	common_opt.conn_bw.conn_bw.conn_bw_rx = BLE_CONN_BW_HIGH;
	common_opt.conn_bw.conn_bw.conn_bw_tx = BLE_CONN_BW_HIGH;
	opt.common_opt = common_opt;

	return sd_ble_opt_set(m_adapter, BLE_COMMON_OPT_CONN_BW, &amp;amp;opt);
}


uint32_t  ScanStart()
{
	uint32_t error_code = sd_ble_gap_scan_start(m_adapter, &amp;amp;m_scanParam);

	if (error_code != NRF_SUCCESS)
	{
		printf(&amp;quot;\nScan start failed with error code: %d&amp;quot;, error_code);
		fflush(stdout);
	}
	else
	{
		printf(&amp;quot;\nScan started&amp;quot;);
		fflush(stdout);
	}

	return error_code;
}


BleManager::BleManager(shared_ptr&amp;lt;Logger&amp;gt; logger)
{
	m_logger = logger;
}

bool BleManager::Scan(const std::string &amp;amp; serialPort)
{
	return  scan(serialPort);
}

bool  BleManager::Connect(std::shared_ptr&amp;lt;IBleDevice&amp;gt; device)
{
	return connect(device);
}

BleManager::~BleManager()
{
}

void BleManager::SetOnDeviceDiscoveredCallback(OnDeviceDiscoveredCallbackType callback) { m_onDeviceDiscoveredCallback = callback; }
void BleManager::SetOnSncDataReadyCallback(OnSncDataReadyCallbackType callback) { m_onSncDataReadyCallback = callback; }
void BleManager::SetOnImuDataReadyCallback(OnImuDataReadyCallbackType callback) { m_onImuDataReadyCallback = callback; };
&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Best regards&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Liav Adi&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Connect to two peripheral devices at once using nRF52 dongle</title><link>https://devzone.nordicsemi.com/thread/181832?ContentTypeID=1</link><pubDate>Fri, 12 Apr 2019 11:44:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1f81408f-d31c-4622-a253-da17a2a05462</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;The s132 v3.x.0 softdevice should support up to 8 concurrent connections from a central to peripherals, but the driver/example you are using might not be configured to support this.&lt;/p&gt;
&lt;p&gt;The latest release of pc-ble-driver (C\C++ version) support&amp;nbsp;&lt;a href="https://github.com/NordicSemiconductor/pc-ble-driver/tree/v4.1.0/hex"&gt;sd_api_v2, sd_api_v3, sd_api_v5, and sd_api_v6&lt;/a&gt;. Can you share your code you are using, and which versions of pc-ble-driver/connectivity firmware you are using?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;br /&gt;Jørgen&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>