void BluetoothHandler::receiveHrNotifications() {

	qDebug() << "YYYY setting up to receive GATT notifications";

	if (!bt_initialised) {
		qDebug() << "Bluetooth libraries are not initialised!";
		return;
	}

	HrDataContainer* hrdc = HrDataContainer::getInstance();
	QString device_addr = hrdc->getCurrentDeviceAddr();
	QString device_name = hrdc->getCurrentDeviceName();
	hrdc->clearData();

	bt_gatt_conn_parm_t conParm;
	conParm.minConn = 0x30;
	conParm.maxConn = 0x50;
	conParm.latency = 0;
	conParm.superTimeout = 50;

	errno= 0;

	if (bt_gatt_connect_service(device_addr.toAscii().constData(), HR_SERVICE_UUID, NULL, &conParm, this) < 0) {
		qDebug() << "YYYY GATT connect service request failed: " + QString::number(errno) + " (" + QString(strerror(errno)) + ")";
	} else {
		qDebug() << "YYYY requested connection to HR service OK";
	}

}
void BluetoothHandler::receiveHrNotifications() {

	qDebug() << "YYYY setting up to receive GATT notifications";

	if (!bt_initialised) {
		qDebug() << "Bluetooth libraries are not initialised!";
		return;
	}

	HrDataContainer* hrdc = HrDataContainer::getInstance();
	QString device_addr = hrdc->getCurrentDeviceAddr();
	QString device_name = hrdc->getCurrentDeviceName();
	hrdc->clearData();

	bt_gatt_conn_parm_t conParm;
	conParm.minConn = 0x30;
	conParm.maxConn = 0x50;
	conParm.latency = 0;
	conParm.superTimeout = 50;

	errno= 0;

	if (bt_gatt_connect_service(device_addr.toAscii().constData(), HR_SERVICE_UUID, NULL, &conParm, this) < 0) {
		qDebug() << "YYYY GATT connect service request failed: " + QString::number(errno) + " (" + QString(strerror(errno)) + ")";
		// there's a known issue where sometimes we get ERRNO=EBUSY (16) when this is not the case and we've connected to the service OK. So for now we ignore this errno value.
		if (errno != 16) {
			Utilities::alert("GATT connect service request failed: " + QString::number(errno));
		}
	} else {
		qDebug() << "YYYY requested connection to HR service OK";
	}

}
void BluetoothHandler::stopHrNotifications() {

	errno= 0;

	HrDataContainer* hrdc = HrDataContainer::getInstance();
	QString device_addr = hrdc->getCurrentDeviceAddr();

	if (bt_gatt_disconnect_service(device_addr.toAscii().constData(), HR_SERVICE_UUID) < 0) {
		qDebug() << "YYYY GATT disconnect service request failed: " + QString::number(errno) + " (" + QString(strerror(errno)) + ")";
	} else {
		qDebug() << "YYYY disconnected from HR service OK";
	}

}
void notifications_cb(int instance, uint16_t handle, const uint8_t *val, uint16_t len, void *userData) {

	Q_UNUSED(instance)
	Q_UNUSED(userData)

	qDebug() << "YYYY notifications call back received";
	if (NULL == val)
		return;

	HrDataContainer* hrdc = HrDataContainer::getInstance();

	if (handle == hrdc->getHrValueHandle()) {
		hrdc->addNotification(val,len);
		hrdc->logMostRecentNotification();
	}

}
void gatt_service_connected(const char *bdaddr, const char *service, int instance, int err, uint16_t connInt, uint16_t latency, uint16_t superTimeout, void *userData) {

	Q_UNUSED(superTimeout)
	Q_UNUSED(userData)
	Q_UNUSED(latency)
	Q_UNUSED(connInt)
	Q_UNUSED(err)

	qDebug() << "YYYY gatt_service_connected";

	QString bdaddr_str = QString(bdaddr);
	QString service_str = QString(service);

	qDebug() << "YYYY registering for notifications";
	errno = 0;
	int rc = bt_gatt_reg_notifications(instance, notifications_cb);
	qDebug() << "YYYY rc from bt_gatt_reg_notifications=" << rc;
	if (rc != 0) {
		qDebug() << "YYYY bt_gatt_reg_notifications errno=" << errno;
		qDebug() << "YYYY bt_gatt_reg_notifications errno=" << strerror(errno);
	} else {
		qDebug() << "YYYY bt_gatt_reg_notifications was presumably OK";
	}

	bt_gatt_characteristic_t* heart_rate_measurement;

	heart_rate_measurement = (bt_gatt_characteristic_t*) malloc(sizeof(bt_gatt_characteristic_t));
	if (NULL == heart_rate_measurement) {
		qDebug() << "YYYY GATT characteristics: Not enough memory";
		bt_gatt_disconnect_instance(instance);
		return;
	}

	int num_characteristics = bt_gatt_characteristics_count(instance);

	if (num_characteristics > -1) {
		qDebug() << QString("YYYY # characteristics: %1").arg(num_characteristics);
		bt_gatt_characteristic_t *characteristicList;

		characteristicList = (bt_gatt_characteristic_t*) malloc(num_characteristics * sizeof(bt_gatt_characteristic_t));
		if (NULL == characteristicList) {
			qDebug() << QString("YYYY GATT characteristics: Not enough memory");
			bt_gatt_disconnect_instance(instance);
			return;
		}

		/* BEGIN WORKAROUND - Temporary fix to address race condition */
		int number = 0;
		do {
			number = bt_gatt_characteristics(instance, characteristicList, num_characteristics);
		} while ((number == -1) && (errno== EBUSY));

		int characteristicListSize = number;

		HrDataContainer *hrdc = HrDataContainer::getInstance();

		for (int i = 0; i < characteristicListSize; i++) {
			qDebug() << "YYYY characteristic: uuid,handle,value_handle:" << characteristicList[i].uuid << "," << characteristicList[i].handle << "," << characteristicList[i].value_handle;
			if (strcmp(characteristicList[i].uuid, HEART_RATE_MEASUREMENT) == 0) {
				qDebug() << "YYYY heart rate characteristic available";
				hrdc->setHrHandle(characteristicList[i].handle);
				hrdc->setHrValueHandle(characteristicList[i].value_handle);
				// enable=1 switches the notification on for the specified characteristic
				qDebug() << "YYYY registering for heart_rate_measurement notification. uuid,handle,value_handle=" << characteristicList[i].uuid << "," << characteristicList[i].handle << "," << characteristicList[i].value_handle;
				errno= 0;
				rc = bt_gatt_enable_notify(instance, &characteristicList[i], 1);
				if (rc != 0) {
					qDebug() << "YYYY bt_gatt_enable_notify errno=" << errno;
					qDebug() << "YYYY bt_gatt_enable_notify errno=" << strerror(errno);
				} else {
					qDebug() << "YYYY bt_gatt_enable_notify was presumably OK";
				}
				qDebug() << "YYYY rc from registering for heart_rate_measurement notification=" << rc;

			} else {
				qDebug() << "YYYY other characteristic: uuid,handle,value_handle=" << characteristicList[i].uuid << "," << characteristicList[i].handle << "," << characteristicList[i].value_handle;
			}
		}

		if (characteristicList != NULL) {
			free(characteristicList);
			characteristicList = NULL;
		}

		/* END WORKAROUND */

		qDebug() << "YYYY done registering for heart_rate_measurement notifications";
	}
}