void gatt_service_disconnected(const char *bdaddr, const char *service, int instance, int reason, void *userData)
{

    Q_UNUSED(userData)
    Q_UNUSED(instance)
    Q_UNUSED(reason)

    QString bdaddr_str = QString(bdaddr);
    QString service_str = QString(service);
    qDebug() << QString("XXXX gatt_service_disconnected: bdaddr:%1 : %2 - %3").arg(bdaddr_str).arg(service_str).arg(parse_service_uuid(service));

    DataContainer *dc = DataContainer::getInstance();

    if (instance == dc->getLinkLossServiceInstance()) {
        qDebug() << "XXXX reacting to link loss service disconnection";
        link_loss_connected = false;
        dc->setLinkLossServiceInstance(0);
        _handler->emitSignalLostLink();
    }

    if (instance == dc->getTxPowerServiceInstance()) {
        qDebug() << "XXXX reacting to tx power service disconnection";
        tx_power_connected = false;
        dc->setTxPowerServiceInstance(0);
    }

    if (instance == dc->getAlertServiceInstance()) {
        qDebug() << "XXXX reacting to immediate alert service disconnection";
        immediate_alert_connected = false;
        dc->setAlertServiceInstance(0);
    }

}
void btEvent(const int event, const char *bt_addr, const char *event_data)
{

    Q_UNUSED(bt_addr)

    QString event_name = btEventName(event);
    qDebug() << "XXXX bluetooth event:" << event_name;

    if (event_data != NULL) {
        QString event_data_str = QString(*event_data);
        qDebug() << "XXXX BT event_data=" << event_data_str;
    } else {
        qDebug() << "XXXX BT event_data=NULL";
    }

    if (event == BT_EVT_LE_DEVICE_CONNECTED) {
        _handler->emitSignalSetMessage("Chicken sensor has connected");
        DataContainer *dc = DataContainer::getInstance();
        dc->setDeviceConnected(true);
        _handler->emitSignalLinkEstablished();
        return;
    }

    if (event == BT_EVT_LE_DEVICE_DISCONNECTED) {
        immediate_alert_connected = false;
        link_loss_connected = false;
        tx_power_connected = false;
        rssi_polling_required = false;
        DataContainer *dc = DataContainer::getInstance();
        dc->setDeviceConnected(false);
        dc->setAlertServiceInstance(0);
        dc->setLinkLossServiceInstance(0);
        dc->setTxPowerServiceInstance(0);
        _handler->emitSignalSetMessage("Chicken sensor has disconnected");
        _handler->emitSignalDisableProximityVisualisation();
        return;
    }
}
void establishHandles(int service_type, int instance)
{
    if (service_type < 1 || service_type > 3) {
        qDebug() << "XXXX invalid service type indicator passed to establishAlertLevelHandle function:" << service_type;
        return;
    }

    const char* characteristic_uuids[] = { ALERT_LEVEL_UUID, ALERT_LEVEL_UUID, TX_POWER_LEVEL_UUID };

    DataContainer *dc = DataContainer::getInstance();

    bt_gatt_characteristic_t* alert_level;

// find the handle of the alert level characteristic
    int num_characteristics = bt_gatt_characteristics_count(instance);
    qDebug() << "YYYY # characteristics=" << num_characteristics;

    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;

        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, characteristic_uuids[service_type - 1]) == 0) {
                qDebug() << "YYYY found alert level characteristic";
                switch (service_type) {
                case INDEX_IMMEDIATE_ALERT_SERVICE:
                    qDebug() << "XXXX CONNECTED TO IMMEDIATE ALERT SERVICE - saving handles";
                    dc->setAlertServiceInstance(instance);
                    dc->setImmediateAlertLevelHandle(characteristicList[i].handle);
                    dc->setImmediateAlertLevelValueHandle(characteristicList[i].value_handle);
                    break;
                case INDEX_LINK_LOSS_SERVICE:
                    qDebug() << "XXXX CONNECTED TO LINK LOSS SERVICE - saving handles";
                    dc->setLinkLossAlertLevelHandle(characteristicList[i].handle);
                    dc->setLinkLossAlertLevelValueHandle(characteristicList[i].value_handle);
                    dc->setLinkLossServiceInstance(instance);
                    break;
                case INDEX_TX_POWER_SERVICE:
                    qDebug() << "XXXX CONNECTED TO TX POWER SERVICE - saving handles";
                    dc->setTxPowerLevelHandle(characteristicList[i].handle);
                    dc->setTxPowerLevelValueHandle(characteristicList[i].value_handle);
                    dc->setTxPowerServiceInstance(instance);
                    break;
                }
            } 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 */
    }
}