This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to run proxy and Nus at the same time

Hi all, 

when I insert ble_nus into mesh_gatt . I realized there are two pulse functions with the same function: 

void ble_nus_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
    if ((p_context == NULL) || (p_ble_evt == NULL))
    {
        return;
    }

    ble_nus_t * p_nus = (ble_nus_t *)p_context;

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            on_connect(p_nus, p_ble_evt);
            break;

        case BLE_GATTS_EVT_WRITE:
            on_write(p_nus, p_ble_evt);
            break;

        case BLE_GATTS_EVT_HVN_TX_COMPLETE:
            on_hvx_tx_complete(p_nus, p_ble_evt);
            break;

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

and 

void mesh_gatt_on_ble_evt(const ble_evt_t * p_ble_evt, void * p_context)
{
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            connect_evt_handle(p_ble_evt);
            break;

        case BLE_GAP_EVT_DISCONNECTED:
            disconnect_evt_handle(p_ble_evt);
            break;

        case BLE_GATTS_EVT_WRITE:
            write_evt_handle(p_ble_evt);
            break;

        case BLE_GATTS_EVT_HVN_TX_COMPLETE:
            tx_complete_handle(p_ble_evt->evt.gatts_evt.conn_handle);
            break;


        /* TODO: The following events should be handled by an SDK module/the application. */
        case BLE_GATTS_EVT_SYS_ATTR_MISSING:
        {
            uint32_t err_code = sd_ble_gatts_service_changed(p_ble_evt->evt.gatts_evt.conn_handle,
                                                             m_gatt.handles.service,
                                                             m_gatt.handles.service);

            /* 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. */
            NRF_MESH_ASSERT((err_code == NRF_SUCCESS) ||
                            (err_code == BLE_ERROR_INVALID_CONN_HANDLE) ||
                            (err_code == NRF_ERROR_INVALID_STATE) ||
                            (err_code == NRF_ERROR_BUSY));
            NRF_MESH_ERROR_CHECK(sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0));
            break;
        }

        case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
        {
            ble_gap_data_length_params_t dl_params;
            memset(&dl_params, BLE_GAP_DATA_LENGTH_AUTO, sizeof(dl_params));
            NRF_MESH_ERROR_CHECK(sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle,
                                                               &dl_params,
                                                               NULL));
            break;
        }

        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            NRF_MESH_ERROR_CHECK(sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle,
                                                             BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
                                                             NULL,
                                                             NULL));
            break;

        case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
        {
            ble_gap_phys_t const phys =
            {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            NRF_MESH_ERROR_CHECK(sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys));
            break;
        }

        case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
            exchange_mtu_req_handle(p_ble_evt);
            break;

        case BLE_GATTS_EVT_SC_CONFIRM:
            break;

        default:
            break;
    }
}

if they let them coexist , when I use nrf_connect connect and use mesh_app connect , It jump to 2 function , and I only want , if I connect to nus , it jump to ble_nus_on_ble_evt , If I connect to proxy , It jump to mesh_gatt_on_ble_evt . Is this feasible? Can you give me advice ? Thank !!!

Parents Reply
  • At the point of the BLE_GAP_EVT_CONNECTED, there is no distinction yet. The differences are only on events like BLE_GATTS_EVT_WRITE and BLE_GATTS_EVT_HVN_TX_COMPLETE. It's the same connection, but one reads/writes to different characteristics. Ones accessing a characteristic, one compares the handle in the p_ble_evt with the handle of the characteristic of the NUS or Proxy to determine if it is being addressed.

Children
  • I have this example, which I am still working on. It's not "clean" as I cann the nus event handler from the mesh gatt event handler in stead of making a dispatcher. But it's a part of a project I've been working on myself.

    At least this code gets into the nus data handler with the data I sent to it. That's as far as I have tested this code.

    void mesh_gatt_on_ble_evt(const ble_evt_t * p_ble_evt, void * p_context)
    {
    
    	/// we need to put in this NUS this somewhere... this not not neat
    	// to do it here... but until I find a better structure to support this
    	// within the mesh sdk.
        ble_nus_on_ble_evt(p_ble_evt, &g_nus); // curious, did the parameters swap on this SDK version?
    	///!!!
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
    
            	// added for nus support
    
    
            	//
    
                connect_evt_handle(p_ble_evt);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                disconnect_evt_handle(p_ble_evt);
                break;
    
            case BLE_GATTS_EVT_WRITE:
                write_evt_handle(p_ble_evt);
                break;
    
            case BLE_GATTS_EVT_HVN_TX_COMPLETE:
                tx_complete_handle(p_ble_evt->evt.gatts_evt.conn_handle);
                break;
    
    
            /* TODO: The following events should be handled by an SDK module/the application. */
            case BLE_GATTS_EVT_SYS_ATTR_MISSING:
            {
            	/*
                uint32_t err_code = sd_ble_gatts_service_changed(p_ble_evt->evt.gatts_evt.conn_handle,
                                                                 m_gatt.handles.service,
                                                                 m_gatt.handles.service);
    
                // 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.
                NRF_MESH_ASSERT((err_code == NRF_SUCCESS) ||
                                (err_code == BLE_ERROR_INVALID_CONN_HANDLE) ||
                                (err_code == NRF_ERROR_INVALID_STATE) ||
                                (err_code == NRF_ERROR_BUSY));
                NRF_MESH_ERROR_CHECK(sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0));
                break;
                */
    
            	// Well... the original code above crashes when adding the NUS. I've used the following
            	// code to handle BLE_GATTS_EVT_SYS_ATTR_MISSING in another NUS based project.
            	// I'd say gatts_service_changes ain't a mesh thing thus this should pose no problem.
            	uint32_t err_code = sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0);
            	break;
            }
    
            case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
            {
                ble_gap_data_length_params_t dl_params;
                memset(&dl_params, BLE_GAP_DATA_LENGTH_AUTO, sizeof(dl_params));
                NRF_MESH_ERROR_CHECK(sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle,
                                                                   &dl_params,
                                                                   NULL));
                break;
            }
    
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                NRF_MESH_ERROR_CHECK(sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle,
                                                                 BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
                                                                 NULL,
                                                                 NULL));
                break;
    
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
            {
                ble_gap_phys_t const phys =
                {
                    .rx_phys = BLE_GAP_PHY_AUTO,
                    .tx_phys = BLE_GAP_PHY_AUTO,
                };
                NRF_MESH_ERROR_CHECK(sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys));
                break;
            }
    
            case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
                exchange_mtu_req_handle(p_ble_evt);
                break;
    
            case BLE_GATTS_EVT_SC_CONFIRM:
                break;
    
            default:
                break;
        }
    }

  • Thank for help !!!

    This my code modified : 

    void mesh_gatt_on_ble_evt(const ble_evt_t * p_ble_evt, void * p_context)
    {
        if ((p_context == NULL) || (p_ble_evt == NULL))
        {
            return;
        }
    
        ble_nus_t * p_nus = (ble_nus_t *)p_context;
        ble_nus_on_ble_evt(p_ble_evt, &p_nus);
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
    //            connect_evt_handle(p_ble_evt);
    
    //            on_connect(p_nus, p_ble_evt);
                connect_evt_handle(p_ble_evt);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                disconnect_evt_handle(p_ble_evt);
                break;
    
            case BLE_GATTS_EVT_WRITE:
                
                on_write(p_nus, p_ble_evt);
                write_evt_handle(p_ble_evt);
                break;
    
            case BLE_GATTS_EVT_HVN_TX_COMPLETE:
                
                on_hvx_tx_complete(p_nus, p_ble_evt);
                tx_complete_handle(p_ble_evt->evt.gatts_evt.conn_handle);
                break;  
    
    
            /* TODO: The following events should be handled by an SDK module/the application. */
            case BLE_GATTS_EVT_SYS_ATTR_MISSING:
            {
    //            uint32_t err_code = sd_ble_gatts_service_changed(p_ble_evt->evt.gatts_evt.conn_handle,
    //                                                             m_gatt.handles.service,
    //                                                             m_gatt.handles.service);
    //
    //            /* 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. */
    //            NRF_MESH_ASSERT((err_code == NRF_SUCCESS) ||
    //                            (err_code == BLE_ERROR_INVALID_CONN_HANDLE) ||
    //                            (err_code == NRF_ERROR_INVALID_STATE) ||
    //                            (err_code == NRF_ERROR_BUSY));
                NRF_MESH_ERROR_CHECK(sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0));
                break;
            }

    But it still error . If I run NUS service , it jump mesh handle and error ?

    NUS part will run correct if I only use :

    case BLE_GATTS_EVT_WRITE:
    on_write(p_nus, p_ble_evt);
    // write_evt_handle(p_ble_evt);
    break;

    case BLE_GATTS_EVT_HVN_TX_COMPLETE:
    on_hvx_tx_complete(p_nus, p_ble_evt);
    // tx_complete_handle(p_ble_evt->evt.gatts_evt.conn_handle);
    break;

    and error if use : 

    case BLE_GATTS_EVT_WRITE:
    on_write(p_nus, p_ble_evt);
    write_evt_handle(p_ble_evt);
    break;

    case BLE_GATTS_EVT_HVN_TX_COMPLETE:
    on_hvx_tx_complete(p_nus, p_ble_evt);
    tx_complete_handle(p_ble_evt->evt.gatts_evt.conn_handle);
    break;

    can you help me , I really need this ! Thank very much !!!

  • DId you initialise the nus? Call nus_init(); after initialize(); in the main(); function?

  • static void initialize(void)
    {
        __LOG_INIT(LOG_SRC_APP | LOG_SRC_ACCESS, LOG_LEVEL_DBG3, LOG_CALLBACK_DEFAULT);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh Light Switch Proxy Server Demo -----\n");
    
        hal_leds_init();
    
        uart_init();
        log_info_init();
        timers_init();
    
    #if BUTTON_BOARD
        ERROR_CHECK(hal_buttons_init(button_event_handler));
    #endif
        uint32_t err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        uint32_t ram_start = 0;
        /* Set the default configuration (as defined through sdk_config.h). */
        err_code = nrf_sdh_ble_default_cfg_set(MESH_SOFTDEVICE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        gap_params_init();
    
    //    gatt_init();
        services_init();
        conn_params_init();
    
        mesh_init();
    }
    
    static void start(void)
    {
    //    rtt_input_enable(app_rtt_input_handler, RTT_INPUT_POLL_PERIOD_MS);
        ERROR_CHECK(mesh_stack_start());
    
        if (!m_device_provisioned)
        {
            static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
            mesh_provisionee_start_params_t prov_start_params =
            {
                .p_static_data    = static_auth_data,
                .prov_complete_cb = provisioning_complete_cb
            };
            ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
        }
    
        const uint8_t *p_uuid = nrf_mesh_configure_device_uuid_get();
        __LOG_XB(LOG_SRC_APP, LOG_LEVEL_INFO, "Device UUID ", p_uuid, NRF_MESH_UUID_SIZE);
    }
    
    int main(void)
    {
        initialize();
        execution_start(start);
    
        for (;;)
        {
            (void)sd_app_evt_wait();
        }
    }

    This is an part of my main . I call nus init() in service_init() function 

Related