Example #1
0
uint32_t conn_mw_ble_gatts_service_changed(uint8_t const * const p_rx_buf,
                                           uint32_t              rx_buf_len,
                                           uint8_t * const       p_tx_buf,
                                           uint32_t * const      p_tx_buf_len)
{
    SER_ASSERT_NOT_NULL(p_rx_buf);
    SER_ASSERT_NOT_NULL(p_tx_buf);
    SER_ASSERT_NOT_NULL(p_tx_buf_len);

    uint16_t conn_handle;
    uint16_t start_handle;
    uint16_t end_handle;

    uint32_t err_code = NRF_SUCCESS;
    uint32_t sd_err_code;

    err_code = ble_gatts_service_changed_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &start_handle,
                                                 &end_handle);
    SER_ASSERT(err_code == NRF_SUCCESS, err_code);

    sd_err_code = sd_ble_gatts_service_changed(conn_handle, start_handle, end_handle);

    err_code = ble_gatts_service_changed_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
    SER_ASSERT(err_code == NRF_SUCCESS, err_code);

    return err_code;
}
Example #2
0
/**@brief     Function updating Service Changed CCCD and indicate a service change to peer.
 *
 * @details   This function will verify the CCCD setting provided with \ref m_ble_peer_data and
 *            update the system attributes accordingly. If Service Change CCCD is set to indicate
 *            then a service change indication will be send to the peer.
 *
 * @retval    NRF_INVALID_STATE if no connection has been established to a central.
 * @return    Any error code returned by SoftDevice function calls.
 */
static uint32_t service_change_indicate()
{
    uint32_t err_code;

    if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
    {
        return NRF_ERROR_INVALID_STATE;
    }

    if (m_ble_peer_data_valid)
    {
        err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
                                             m_ble_peer_data.sys_serv_attr,
                                             sizeof(m_ble_peer_data.sys_serv_attr),
                                             BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }

        err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
                                             NULL,
                                             0,
                                             BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }

        err_code = sd_ble_gatts_service_changed(m_conn_handle, DFU_SERVICE_HANDLE, BLE_HANDLE_MAX);
        if ((err_code == BLE_ERROR_INVALID_CONN_HANDLE) ||
            (err_code == NRF_ERROR_INVALID_STATE) ||
            (err_code == BLE_ERROR_NO_TX_BUFFERS))
        {
            // Those errors can be expected when sending trying to send Service Changed Indication
            // if the CCCD is not set to indicate. Thus set the returning error code to success.
            err_code = NRF_SUCCESS;
        }
    }
    else
    {
        err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
    }

    return err_code;
}
/**
  * Callback when a BLE SYS_ATTR_MISSING.
  */
static void bleSysAttrMissingCallback(const GattSysAttrMissingCallbackParams *params)
{
    int complete = 0;
    deviceID = 255;

    dm_handle_t dm_handle = {0,0,0,0};

    int ret = dm_handle_get(params->connHandle, &dm_handle);

    if (ret == 0)
        deviceID = dm_handle.device_id;

    if(manager->storage != NULL && deviceID < MICROBIT_BLE_MAXIMUM_BONDS)
    {
        ManagedString key("bleSysAttrs");

        KeyValuePair* bleSysAttrs = manager->storage->get(key);

        BLESysAttributeStore attribStore;
        BLESysAttribute attrib;

        if(bleSysAttrs != NULL)
        {
            //restore our sysAttrStore
            memcpy(&attribStore, bleSysAttrs->value, sizeof(BLESysAttributeStore));
            delete bleSysAttrs;

            attrib = attribStore.sys_attrs[deviceID];

            ret = sd_ble_gatts_sys_attr_set(params->connHandle, attrib.sys_attr, sizeof(attrib.sys_attr), BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);

            complete = 1;

            if(ret == 0)
                ret = sd_ble_gatts_service_changed(params->connHandle, 0x000c, 0xffff);
        }
    }

    if (!complete)
        sd_ble_gatts_sys_attr_set(params->connHandle, NULL, 0, 0);

}
/**
  * Callback when a BLE GATT connect occurs.
  */
static void bleConnectionCallback(const Gap::ConnectionCallbackParams_t *reason)
{
    // configure the stack to hold on to CPU during critical timing events.
    // mbed-classic performs __disabe_irq calls in its timers, which can cause MIC failures
    // on secure BLE channels.
    ble_common_opt_radio_cpu_mutex_t opt;
    opt.enable = 1;
    sd_ble_opt_set(BLE_COMMON_OPT_RADIO_CPU_MUTEX, (const ble_opt_t *)&opt);

    // Ensure that there's no stale, cached information in the client... invalidate all characteristics.
    uint16_t len = 8;

    // Configure the ServiceChanged characteristic to receive service changed indications
    // TODO: This is really a workaround as we can't maintain persistent state on the micro:bit across USB
    // reprogramming flashes.... yet.
    uint8_t data[] = {0x0B,0x00,0x02,0x00,0x02,0x00,0xB8,0x46};

    sd_ble_gatts_sys_attr_set(reason->handle, data, len, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS); 
    sd_ble_gatts_service_changed(reason->handle, 0x000c, 0xffff); 
}
Example #5
0
/**@brief Function for loading application-specific context after establishing a secure connection.
 *
 * @details This function will load the application context and check if the ATT table is marked as
 *          changed. If the ATT table is marked as changed, a Service Changed Indication
 *          is sent to the peer if the Service Changed CCCD is set to indicate.
 *
 * @param[in] p_handle The Device Manager handle that identifies the connection for which the context
 *                     should be loaded.
 */
static void app_context_load(dm_handle_t const * p_handle)
{
    uint32_t                 err_code;
    static uint32_t          context_data;
    dm_application_context_t context;

    context.len    = sizeof(context_data);
    context.p_data = (uint8_t *)&context_data;

    err_code = dm_application_context_get(p_handle, &context);
    if (err_code == NRF_SUCCESS)
    {
        // Send Service Changed Indication if ATT table has changed.
        if ((context_data & (DFU_APP_ATT_TABLE_CHANGED << DFU_APP_ATT_TABLE_POS)) != 0)
        {
            err_code = sd_ble_gatts_service_changed(m_conn_handle, APP_SERVICE_HANDLE_START, BLE_HANDLE_MAX);
            if ((err_code != NRF_SUCCESS) &&
                (err_code != BLE_ERROR_INVALID_CONN_HANDLE) &&
                (err_code != NRF_ERROR_INVALID_STATE) &&
                (err_code != BLE_ERROR_NO_TX_PACKETS) &&
                (err_code != NRF_ERROR_BUSY) &&
                (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING))
            {
                APP_ERROR_HANDLER(err_code);
            }
        }

        err_code = dm_application_context_delete(p_handle);
        APP_ERROR_CHECK(err_code);
    }
    else if (err_code == DM_NO_APP_CONTEXT)
    {
        // No context available. Ignore.
    }
    else
    {
        APP_ERROR_HANDLER(err_code);
    }
}