Exemple #1
0
/**@brief Function for handling the response on service discovery.
 *
 * @details This function will validate the response.
 *          Invalid response - Handle discovery failure.
 *          Valid response   - Initiate Characteristic Discovery Procedure.
 */
static void event_discover_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt)
{
    if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS)
    {
        // We have received an  unexpected result.
        // As we are in a connected state, but can not continue
        // our service discovery, we will go to running state.
        handle_discovery_failure(p_ans, p_ble_evt->evt.gattc_evt.gatt_status);
    }
    else
    {
        BLE_UUID_COPY_INST(m_service.service.uuid,
                           p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[0].uuid);

        if (p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count > 0)
        {
            const ble_gattc_service_t * p_service;

            p_service = &(p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[0]);

            m_service.service.handle_range.start_handle = p_service->handle_range.start_handle;
            m_service.service.handle_range.end_handle   = p_service->handle_range.end_handle;

            characteristic_disc_req_send(p_ans, &(m_service.service.handle_range));
        }
        else
        {
            // If we receive an answer, but it contains no service, we just go to state: Running.
            handle_discovery_failure(p_ans, p_ble_evt->evt.gattc_evt.gatt_status);
        }
    }
}
Exemple #2
0
/**@brief Function for handling of descriptor discovery responses.
 *
 * @details This function will validate and store the descriptor received.
 *          If not all descriptors are discovered it will continue the descriptor discovery
 *          procedure, otherwise it will continue to running state.
 *          If we receive a GATT Client error, we will go to handling of discovery failure.
 */
static void event_descriptor_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt)
{
    if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND ||
        p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INVALID_HANDLE)
    {
        handle_discovery_failure(p_ans, NRF_ERROR_NOT_FOUND);
    }
    else if (p_ble_evt->evt.gattc_evt.gatt_status)
    {
        // We have received an unexpected result.
        // As we are in a connected state, but can not continue
        // our descriptor discovery, we will go to running state.
        handle_discovery_failure(p_ans, p_ble_evt->evt.gattc_evt.gatt_status);
    }
    else
    {
        if (p_ble_evt->evt.gattc_evt.params.desc_disc_rsp.count > 0)
        {
            descriptor_set(&m_service, &(p_ble_evt->evt.gattc_evt.params.desc_disc_rsp.descs[0]));
        }

        if (m_service.new_alert.handle_cccd == BLE_ANS_INVALID_HANDLE ||
            m_service.unread_alert_status.handle_cccd == BLE_ANS_INVALID_HANDLE)
        {
            descriptor_disc_req_send(p_ans);
        }
        else
        {
            connection_established(p_ans);
        }
    }
}
Exemple #3
0
/**@brief Function for executing the Characteristic Descriptor Discovery Procedure.
 */
static void descriptor_disc_req_send(const ble_ans_c_t * p_ans)
{
    ble_gattc_handle_range_t descriptor_handle;
    uint32_t                 err_code = NRF_SUCCESS;

    // If we have not discovered descriptors for all characteristics,
    // we will discover next descriptor.
    if (m_service.new_alert.handle_cccd == BLE_ANS_INVALID_HANDLE)
    {
        descriptor_handle.start_handle = m_service.new_alert.handle_value + 1;
        descriptor_handle.end_handle = m_service.new_alert.handle_value + 1;

        err_code = sd_ble_gattc_descriptors_discover(p_ans->conn_handle, &descriptor_handle);
    }
    else if (m_service.unread_alert_status.handle_cccd == BLE_ANS_INVALID_HANDLE)
    {
        descriptor_handle.start_handle = m_service.unread_alert_status.handle_value + 1;
        descriptor_handle.end_handle = m_service.unread_alert_status.handle_value + 1;

        err_code = sd_ble_gattc_descriptors_discover(p_ans->conn_handle, &descriptor_handle);
    }

    if (err_code == NRF_SUCCESS)
    {
        m_client_state = STATE_DISC_DESC;
    }
    else
    {
        handle_discovery_failure(p_ans, err_code);
    }
}
Exemple #4
0
/**@brief Function for executing the Characteristic Discovery Procedure.
 */
static void characteristic_disc_req_send(const ble_ans_c_t *              p_ans,
                                         const ble_gattc_handle_range_t * p_handle)
{
    uint32_t err_code;

    // With valid service, we should discover characteristics.
    err_code = sd_ble_gattc_characteristics_discover(p_ans->conn_handle, p_handle);

    if (err_code == NRF_SUCCESS)
    {
        m_client_state = STATE_DISC_CHAR;
    }
    else
    {
        handle_discovery_failure(p_ans, err_code);
    }
}
Exemple #5
0
/**@brief Function for executing the Service Discovery Procedure.
 */
static void service_disc_req_send(const ble_ans_c_t * p_ans)
{
    uint16_t   handle = START_HANDLE_DISCOVER;
    ble_uuid_t ans_uuid;
    uint32_t   err_code;

    // Discover services on uuid Alert Notification.
    BLE_UUID_BLE_ASSIGN(ans_uuid, BLE_UUID_ALERT_NOTIFICATION_SERVICE);

    err_code = sd_ble_gattc_primary_services_discover(p_ans->conn_handle, handle, &ans_uuid);
    if (err_code != NRF_SUCCESS)
    {
        handle_discovery_failure(p_ans, err_code);
    }
    else
    {
        m_client_state = STATE_DISC_SERV;
    }
}
/**@brief Function for executing the Service Discovery Procedure.
 */
static void service_disc_req_send(const ble_ancs_c_t * p_ancs)
{
    uint16_t   handle = START_HANDLE_DISCOVER;
    ble_uuid_t ancs_uuid;
    uint32_t   err_code;

    // Discover services on uuid for ANCS.
    BLE_UUID_BLE_ASSIGN(ancs_uuid, BLE_UUID_APPLE_NOTIFICATION_CENTER_SERVICE);
    ancs_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN;

    err_code = sd_ble_gattc_primary_services_discover(p_ancs->conn_handle, handle, &ancs_uuid);
    if (err_code != NRF_SUCCESS)
    {
        handle_discovery_failure(p_ancs, err_code);
    }
    else
    {
        m_client_state = STATE_DISC_SERV;
    }
}
Exemple #7
0
/**@brief Function for handling a characteristic discovery response event.
 *
 * @details This function will validate and store the characteristics received.
 *          If not all characteristics are discovered it will continue the characteristic discovery
 *          procedure, otherwise it will continue with the descriptor discovery procedure.
 *          If we receive a GATT Client error, we will go to handling of discovery failure.
 */
static void event_characteristic_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt)
{
    if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND ||
        p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INVALID_HANDLE)
    {
        if ((m_service.alert_notif_ctrl_point.handle_value == 0)    ||
            (m_service.suported_new_alert_cat.handle_value == 0)    ||
            (m_service.suported_unread_alert_cat.handle_value == 0) ||
            (m_service.new_alert.handle_value == 0)                 ||
            (m_service.unread_alert_status.handle_value == 0))
        {
            // At least one required characteristic is missing on the server side.
            handle_discovery_failure(p_ans, NRF_ERROR_NOT_FOUND);
        }
        else
        {
            descriptor_disc_req_send(p_ans);
        }
    }
    else if (p_ble_evt->evt.gattc_evt.gatt_status)
    {
        // We have received an  unexpected result.
        // As we are in a connected state, but can not continue
        // our service discovery, we must go to running state.
        handle_discovery_failure(p_ans, p_ble_evt->evt.gattc_evt.gatt_status);
    }
    else
    {
        uint32_t                 i;
        const ble_gattc_char_t * p_char_resp = NULL;

        // Iterate trough the characteristics and find the correct one.
        for (i = 0; i < p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count; i++)
        {
            p_char_resp = &(p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[i]);
            switch (p_char_resp->uuid.uuid)
            {
                case BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR:
                    characteristics_set(&m_service.alert_notif_ctrl_point, p_char_resp);
                    break;

                case BLE_UUID_UNREAD_ALERT_CHAR:
                    characteristics_set(&m_service.unread_alert_status, p_char_resp);
                    break;

                case BLE_UUID_NEW_ALERT_CHAR:
                    characteristics_set(&m_service.new_alert, p_char_resp);
                    break;

                case BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR:
                    characteristics_set(&m_service.suported_unread_alert_cat, p_char_resp);
                    break;

                case BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR:
                    characteristics_set(&m_service.suported_new_alert_cat, p_char_resp);
                    break;

                default:
                    // No implementation needed.
                    break;
            }
        }

        if (p_char_resp != NULL)
        {
            // If not all characteristics are received, we do a 2nd/3rd/... round.
            ble_gattc_handle_range_t char_handle;

            char_handle.start_handle = p_char_resp->handle_value + 1;
            char_handle.end_handle   = m_service.service.handle_range.end_handle;

            characteristic_disc_req_send(p_ans, &char_handle);
        }
        else
        {
            characteristic_disc_req_send(p_ans, &(m_service.service.handle_range));
        }
    }
}