diff options
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/external/lwip/src/port/nrf_platform_port.c')
-rw-r--r-- | thirdparty/nRF5_SDK_15.0.0_a53641a/external/lwip/src/port/nrf_platform_port.c | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/lwip/src/port/nrf_platform_port.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/lwip/src/port/nrf_platform_port.c new file mode 100644 index 0000000..b6cdd5d --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/lwip/src/port/nrf_platform_port.c @@ -0,0 +1,352 @@ +/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. + * + * The information contained herein is property of Nordic Semiconductor ASA. + * Terms and conditions of usage are described in detail in NORDIC + * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. + * + * Licensees are granted free, non-transferable use of the information. NO + * WARRANTY of ANY KIND is provided. This heading must NOT be removed from + * the file. + * + */ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/netif.h" +#include "lwip/ip6.h" +#include "sdk_config.h" +#include "app_timer.h" +#include "ble_ipsp.h" +#include "ble_6lowpan.h" +#include "mem_manager.h" +#include "iot_context_manager.h" +#include "nrf_platform_port.h" + +/** + * @defgroup nrf_driver_debug_log Module's Log Macros + * @details Macros used for creating module logs which can be useful in understanding handling + * of events or actions on API requests. These are intended for debugging purposes and + * can be enabled by defining the NRF_DRIVER_ENABLE_LOGS. + * @note If NRF_LWIP_DRIVER_CONFIG_LOG_ENABLED is disabled, having NRF_DRIVER_ENABLE_LOGS has no effect. + * @{ + */ + +#if NRF_LWIP_DRIVER_CONFIG_LOG_ENABLED + +#define NRF_LOG_MODULE_NAME LwIP + +#define NRF_LOG_LEVEL NRF_LWIP_DRIVER_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NRF_LWIP_DRIVER_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR NRF_LWIP_DRIVER_CONFIG_DEBUG_COLOR + +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); + +#define NRF_DRIVER_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */ +#define NRF_DRIVER_LOG NRF_LOG_INFO /**< Used for logging details. */ +#define NRF_DRIVER_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */ +#define NRF_DRIVER_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */ + +#define NRF_DRIVER_ENTRY() NRF_DRIVER_TRC(">> %s", __func__) +#define NRF_DRIVER_EXIT() NRF_DRIVER_TRC("<< %s", __func__) + +#else // NRF_LWIP_DRIVER_CONFIG_LOG_ENABLED + +#define NRF_DRIVER_TRC(...) /**< Disables traces. */ +#define NRF_DRIVER_LOG(...) /**< Disables loggs. */ +#define NRF_DRIVER_DUMP(...) /**< Disables dumping of octet streams. */ +#define NRF_DRIVER_ERR(...) /**< Disables error logs. */ + +#define NRF_DRIVER_ENTRY(...) +#define NRF_DRIVER_EXIT(...) + +#endif // NRF_LWIP_DRIVER_CONFIG_LOG_ENABLED + +/** Driver table to maintain mapping between IP interface and Bluetooth as transport. */ +struct blenetif { + iot_interface_t * p_ble_interface; + struct netif netif; +}; + +struct blenetif m_blenetif_table[BLE_6LOWPAN_MAX_INTERFACE]; /**< Table maintaining network interface of LwIP and also corresponding 6lowpan interface. */ + +/** @brief Function to add received packet to pbuf queue and notify the stack of received packet. */ +static void blenetif_input(struct netif * p_netif, uint8_t * p_payload, uint16_t payload_len) +{ + struct pbuf * p_buffer; + + NRF_DRIVER_ENTRY(); + NRF_DRIVER_DUMP(p_payload, payload_len); + + //Allocate a pbuf chain of pbufs from the pool. + p_buffer = pbuf_alloc(PBUF_RAW, payload_len, PBUF_REF); + + if (p_buffer != NULL) + { + p_buffer->payload = p_payload; + p_buffer->len = payload_len; + p_buffer->tot_len = payload_len; + if (ip6_input(p_buffer, p_netif) != ERR_OK) + { + NRF_DRIVER_LOG("IP Stack returned error."); + } + UNUSED_VARIABLE(pbuf_free(p_buffer)); + } + + NRF_DRIVER_EXIT(); +} + + +/** @brief Network interface output function registered with LwIP to send packets on 6lowpan. */ +static err_t blenetif_output(struct netif * p_netif, struct pbuf * p_buffer, const ip6_addr_t * p_addr) +{ + struct blenetif * p_blenetif = (struct blenetif *)p_netif->state; + uint8_t * p_payload; + err_t error_code = ERR_MEM; + const uint16_t requested_len = p_buffer->len; + + + NRF_DRIVER_ENTRY(); + NRF_DRIVER_DUMP(p_buffer->payload, requested_len); + + p_payload = nrf_malloc(p_buffer->len); + + if (NULL != p_payload) + { + memcpy(p_payload, p_buffer->payload, p_buffer->len); + uint32_t retval = ble_6lowpan_interface_send(p_blenetif->p_ble_interface, + p_payload, + requested_len); + if (retval != NRF_SUCCESS) + { + NRF_DRIVER_ERR("Failed to send IP packet, reason 0x%08X", retval); + nrf_free(p_payload); + } + else + { + error_code = ERR_OK; + } + } + else + { + NRF_DRIVER_ERR("Failed to allocate memory for output packet"); + } + + NRF_DRIVER_EXIT(); + + return error_code; + +} + + +/** @brief Initialization once network interface has been added. */ +static err_t blenetif_init(struct netif * p_netif) +{ + //Set link MTU size. + p_netif->mtu = BLE_IPSP_MTU; + + //Device capabilities and link status + p_netif->flags = NETIF_FLAG_LINK_UP; + + //Indicate interface link is up. + netif_set_up(p_netif); + + //Enable Address Auto configuration. + p_netif->ip6_autoconfig_enabled = 1; + + return ERR_OK; +} + + +/**@brief Callback registered with 6lowpan to receive asynchronous events. */ +static void blenetif_transport_callback(iot_interface_t * p_interface, + ble_6lowpan_event_t * p_event) +{ + uint32_t index; + uint32_t err_code; + struct blenetif * p_blenetif = NULL; + + // Search network interface added for the 6lowpan interface that has generated the event. + for (index = 0; index < BLE_6LOWPAN_MAX_INTERFACE; index++) + { + if (p_interface == m_blenetif_table[index].p_ble_interface) + { + p_blenetif = &m_blenetif_table[index]; + break; + } + } + + switch(p_event->event_id) + { + case BLE_6LO_EVT_INTERFACE_ADD: + { + // If no existing interface was found, allocate a new one. + if (p_blenetif == NULL) + { + for (index = 0; index < BLE_6LOWPAN_MAX_INTERFACE; index++) + { + if (m_blenetif_table[index].p_ble_interface == NULL) + { + p_blenetif = &m_blenetif_table[index]; + p_blenetif->p_ble_interface = p_interface; + break; + } + } + } + else + { + // Interface already exists, this is an error, should not happen. + break; + } + + err_code = iot_context_manager_table_alloc(p_interface); + + if (err_code == NRF_SUCCESS) + { + NRF_DRIVER_LOG("Successfully allocated context table!"); + } + else + { + NRF_DRIVER_ERR("Failed to allocate context table!"); + } + +#if (IPV6_LL_ADDR_SIZE == 6) + memcpy(p_blenetif->netif.hwaddr, p_interface->local_addr.identifier, 3); + memcpy(p_blenetif->netif.hwaddr + 3, p_interface->local_addr.identifier + 5, 3); +#else + memcpy(p_blenetif->netif.hwaddr, p_interface->local_addr.identifier, IPV6_LL_ADDR_SIZE); +#endif + p_blenetif->netif.hwaddr_len = IPV6_LL_ADDR_SIZE; + + UNUSED_VARIABLE(netif_add(&p_blenetif->netif, p_blenetif, blenetif_init, NULL)); + + p_blenetif->netif.ip6_addr[0].addr[0] = HTONL(0xFE800000); + p_blenetif->netif.ip6_addr[0].addr[1] = HTONL(0x00000000); + p_blenetif->netif.ip6_addr[0].addr[2] = *((u32_t *) (&p_interface->local_addr.identifier[0])); + p_blenetif->netif.ip6_addr[0].addr[3] = *((u32_t *) (&p_interface->local_addr.identifier[4])); + + // Flip local/universal bit. + p_blenetif->netif.ip6_addr[0].addr[2] ^= IPV6_IID_FLIP_VALUE; + p_blenetif->netif.ip6_addr_state[0] = IP6_ADDR_TENTATIVE; + + p_blenetif->netif.output_ip6 = blenetif_output; + + nrf_driver_interface_up(p_interface); + + break; + } + case BLE_6LO_EVT_INTERFACE_DELETE: + { + if (p_blenetif != NULL) + { + netif_remove(&p_blenetif->netif); + p_blenetif->p_ble_interface = NULL; + + err_code = iot_context_manager_table_free(p_interface); + + if(err_code == NRF_SUCCESS) + { + NRF_DRIVER_ERR("Successfully freed context table!"); + } + nrf_driver_interface_down(p_interface); + } + break; + } + case BLE_6LO_EVT_INTERFACE_DATA_RX: + { + if (p_blenetif != NULL) + { + // Handle received IP packet. + blenetif_input(&p_blenetif->netif, + p_event->event_param.rx_event_param.p_packet, + p_event->event_param.rx_event_param.packet_len); + nrf_free( p_event->event_param.rx_event_param.p_packet); + } + else + { + NRF_DRIVER_ERR("Dropping packet, unknown interface."); + } + break; + } + default: + break; + } +} + + +/**@brief Driver initialization. */ +uint32_t nrf_driver_init(void) +{ + uint32_t err_code; + uint32_t index; + ble_6lowpan_init_t init_param; + + init_param.event_handler = blenetif_transport_callback; + init_param.p_eui64 = EUI64_LOCAL_IID; + + err_code = iot_context_manager_init(); + + if(err_code == NRF_SUCCESS) + { + /* 6lowpan initialization and callback registration. */ + err_code = ble_6lowpan_init(&init_param); + + for (index = 0; index < BLE_6LOWPAN_MAX_INTERFACE; index++) + { + m_blenetif_table[index].p_ble_interface = NULL; + } + } + + return err_code; +} + + +/**@brief Message function to redirect LwIP debug traces to nRF tracing. */ +void nrf_message(const char * m) +{ + NRF_DRIVER_LOG(m); +} + + +/**@brief Interface implementation expected by the LwIP stack to get system ticks. */ +u32_t sys_now(void) +{ + u32_t sys_tick; + + sys_tick = app_timer_cnt_get(); + + //Note: In case prescaler value is changed, this calculation to get sys tick applies. + //Currently, this is not used for saving in code execution as sys_now is called + //often. + + //sys_tick = ROUNDED_DIV(((sys_tick & 0x00FFFFF) * (NRF_DRIVER_TIMER_PRESCALER + 1) * 1000), APP_TIMER_CLOCK_FREQ); + //sys_tick *= 8; + return sys_tick; +} + +void mem_init(void) +{ +} + +void *mem_trim(void *mem, mem_size_t size) +{ + return nrf_realloc(mem, size); +} + +void *mem_malloc(mem_size_t size) +{ + return nrf_malloc(size); +} + +void *mem_calloc(mem_size_t count, mem_size_t size) +{ + return nrf_calloc(count, size); +} + +void mem_free(void *mem) +{ + nrf_free(mem); +} |