222 lines
7.7 KiB
C
Raw Normal View History

2025-08-19 09:49:41 +08:00
/**
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <string.h>
#include "app_error.h"
#include "app_scheduler.h"
#include "ser_config.h"
#include "ser_conn_handlers.h"
#include "ser_conn_event_encoder.h"
#include "ser_conn_pkt_decoder.h"
#include "ser_conn_dtm_cmd_decoder.h"
#include "nrf_sdh.h"
#ifdef BLE_STACK_SUPPORT_REQD
#include "conn_ble_gap_sec_keys.h"
#include "conn_ble_user_mem.h"
#include "conn_ble_l2cap_sdu_pool.h"
#endif
/** @file
*
* @defgroup ser_conn_handlers Events handlers for the Connectivity Chip.
* @{
* @ingroup sdk_lib_serialization
*
* @brief A module to handle the Connectivity application events.
*
* @details There are two types of events in the Connectivity application: BLE events generated by
* the SoftDevice and events generated by the HAL Transport layer.
*/
/** Parameters of a received packet. */
static ser_hal_transport_evt_rx_pkt_received_params_t m_rx_pkt_received_params;
/** Indicator of received packet that should be process. */
static bool m_rx_pkt_to_process = false;
static ser_conn_on_no_mem_t m_on_no_mem_handler;
void ser_conn_on_no_mem_handler_set(ser_conn_on_no_mem_t handler)
{
m_on_no_mem_handler = handler;
}
void ser_conn_on_no_mem_handler(void)
{
if (m_on_no_mem_handler)
{
m_on_no_mem_handler();
}
}
void ser_conn_hal_transport_event_handle(ser_hal_transport_evt_t event)
{
switch (event.evt_type)
{
case SER_HAL_TRANSP_EVT_TX_PKT_SENT:
{
/* SoftDevice event or response to received packet was sent, so unblock the application
* scheduler to process a next event. */
app_sched_resume();
/* Check if chip is ready to enter DTM mode. */
ser_conn_is_ready_to_enter_dtm();
break;
}
case SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING:
{
/* The connectivity side has started receiving a packet. Temporary block processing
* SoftDevice events. It is going to be unblocked when a response for the packet will
* be sent. This prevents communication block. */
app_sched_pause();
break;
}
case SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED:
{
/* We can NOT add received packets as events to the application scheduler queue because
* received packets have to be processed before SoftDevice events but the scheduler
* queue do not have priorities. */
memcpy(&m_rx_pkt_received_params, &event.evt_params.rx_pkt_received,
sizeof (ser_hal_transport_evt_rx_pkt_received_params_t));
m_rx_pkt_to_process = true;
break;
}
case SER_HAL_TRANSP_EVT_RX_PKT_DROPPED:
{
APP_ERROR_CHECK(SER_WARNING_CODE);
break;
}
case SER_HAL_TRANSP_EVT_PHY_ERROR:
{
APP_ERROR_CHECK(NRF_ERROR_FORBIDDEN);
break;
}
default:
{
/* do nothing */
break;
}
}
}
uint32_t ser_conn_rx_process(void)
{
uint32_t err_code = NRF_SUCCESS;
if (m_rx_pkt_to_process)
{
/* No critical section needed on m_rx_pkt_to_process parameter because it is not possible
* to get next packet before sending a response. */
m_rx_pkt_to_process = false;
err_code = ser_conn_received_pkt_process(&m_rx_pkt_received_params);
}
return err_code;
}
#ifdef BLE_STACK_SUPPORT_REQD
void ser_conn_reset(void)
{
conn_ble_gap_sec_keys_init();
conn_ble_user_mem_init();
#ifndef S112
conn_ble_l2cap_sdu_pool_init();
#endif
}
NRF_SDH_BLE_OBSERVER(m_ble_observer, 0, ser_conn_ble_event_handle, NULL);
void ser_conn_ble_event_handle(ble_evt_t const * p_ble_evt, void * p_context)
{
uint32_t err_code = NRF_SUCCESS;
/* We can NOT encode and send BLE events here. SoftDevice handler implemented in
* softdevice_handler.c pull all available BLE events at once but we need to reschedule between
* encoding and sending every BLE event because sending a response on received packet has higher
* priority than sending a BLE event. Solution for that is to put BLE events into application
* scheduler queue to be processed at a later time. */
err_code = app_sched_event_put(p_ble_evt, p_ble_evt->header.evt_len,
ser_conn_ble_event_encoder);
APP_ERROR_CHECK(err_code);
uint16_t free_space = app_sched_queue_space_get();
/* If scheduler queue is full in 75% (arbitrary value) stop pulling new events.
* Some space in scheduler is left for other possible events (e.g. events from USB CDC ACM)
*/
if (free_space < (SER_CONN_SCHED_QUEUE_SIZE / 4))
{
nrf_sdh_suspend();
}
}
#endif // BLE_STACK_SUPPORT_REQD
#ifdef ANT_STACK_SUPPORT_REQD
NRF_SDH_ANT_OBSERVER(m_ant_observer, 0, ser_conn_ant_event_handle, NULL);
void ser_conn_ant_event_handle(ant_evt_t * p_ant_evt, void * p_context)
{
uint32_t err_code = NRF_SUCCESS;
/* We can NOT encode and send ANT events here. SoftDevice handler implemented in
* softdevice_handler.c pull all available ANT events at once but we need to reschedule between
* encoding and sending every ANT event because sending a response on received packet has higher
* priority than sending an ANT event. Solution for that is to put ANT events into application
* scheduler queue to be processed at a later time. */
err_code = app_sched_event_put(p_ant_evt, sizeof (ant_evt_t),
ser_conn_ant_event_encoder);
APP_ERROR_CHECK(err_code);
uint16_t free_space = app_sched_queue_space_get();
if (!free_space)
{
// Queue is full. Do not pull new events.
nrf_sdh_suspend();
}
}
#endif // ANT_STACK_SUPPORT_REQD
/** @} */