Esempio n. 1
0
/**@brief Callback handler to receive data on UDP port.
 *
 * @param[in]   p_socket         Socket identifier.
 * @param[in]   p_ip_header      IPv6 header containing source and destination addresses.
 * @param[in]   p_udp_header     UDP header identifying local and remote endpoints.
 * @param[in]   process_result   Result of data reception, there could be possible errors like
 *                               invalid checksum etc.
 * @param[in]   iot_pbuffer_t    Packet buffer containing the received data packet.
 *
 * @retval      NRF_SUCCESS      Indicates received data was handled successfully, else an error
 *                               code indicating reason for failure.
 */
uint32_t rx_udp_port_app_handler(const udp6_socket_t * p_socket,
                                 const ipv6_header_t * p_ip_header,
                                 const udp6_header_t * p_udp_header,
                                 uint32_t              process_result,
                                 iot_pbuffer_t       * p_rx_packet)
{
    // APPL_LOG("[APPL]: Got UDP6 data on socket 0x%08lx\r\n", p_socket->socket_id);
    // APPL_LOG("[APPL]: Source IPv6 Address: ");
    // APPL_ADDR(p_ip_header->srcaddr);

    APP_ERROR_CHECK(process_result);

    // Print PORTs
    // APPL_LOG("[APPL]: UDP Destination port: %lx\r\n", HTONS(p_udp_header->destport));
    // APPL_LOG("[APPL]: UDP Source port: %lx\r\n",      HTONS(p_udp_header->srcport));

    // UDP packet received from the Client node.
    APPL_LOG("[APPL]: Received UDP packet sequence number: %ld\r\n", \
             uint32_decode(&p_rx_packet->p_payload[0]));

    iot_pbuffer_alloc_param_t   pbuff_param;
    iot_pbuffer_t             * p_tx_buffer;

    pbuff_param.flags  = PBUFFER_FLAG_DEFAULT;
    pbuff_param.type   = UDP6_PACKET_TYPE;
    pbuff_param.length = p_rx_packet->length;

    // Allocate packet buffer.
    uint32_t err_code = iot_pbuffer_allocate(&pbuff_param, &p_tx_buffer);
    APP_ERROR_CHECK(err_code);

    memcpy(p_tx_buffer->p_payload, p_rx_packet->p_payload, p_rx_packet->length);

    // Send back the received packet payload without any modification. 
    err_code = udp6_socket_sendto(&m_udp_socket, &p_ip_header->srcaddr, HTONS(UDP_PORT), p_tx_buffer);
    APP_ERROR_CHECK(err_code);

    m_display_state  = LEDS_TX_UDP_PACKET;
    m_udp_tx_occured = true;

    return NRF_SUCCESS;
}
Esempio n. 2
0
/**@brief Timer callback used for transmitting Echo Request and UDP6 packets depending on
 *        application state.
 *
 * @param[in]   p_context   Pointer used for passing context. No context used in this application.
 */
static void tx_timeout_handler(void * p_context)
{
    uint32_t err_code;

    switch (m_node_state)
    {
        case APP_STATE_IPV6_IF_DOWN:
        {
            return;
        }
        case APP_STATE_IPV6_IF_UP:
        {
            APPL_LOG("[APPL]: Ping remote node. \r\n");

            iot_pbuffer_alloc_param_t   pbuff_param;
            iot_pbuffer_t             * p_buffer;

            pbuff_param.flags  = PBUFFER_FLAG_DEFAULT;
            pbuff_param.type   = ICMP6_PACKET_TYPE;
            pbuff_param.length = ICMP6_ECHO_REQUEST_PAYLOAD_OFFSET + 10;

            // Allocate packet buffer.
            err_code = iot_pbuffer_allocate(&pbuff_param, &p_buffer);
            APP_ERROR_CHECK(err_code);

            ipv6_addr_t dest_ipv6_addr;
            memcpy(&dest_ipv6_addr.u8[0], (uint8_t[]){SERVER_IPV6_ADDRESS}, IPV6_ADDR_SIZE);

            iot_interface_t * p_interface;
            ipv6_addr_t       src_ipv6_addr;
            err_code = ipv6_address_find_best_match(&p_interface,
                                                    &src_ipv6_addr,
                                                    &dest_ipv6_addr);
            APP_ERROR_CHECK(err_code);

            memset(p_buffer->p_payload + ICMP6_ECHO_REQUEST_PAYLOAD_OFFSET, 'A', 10);

            // Send Echo Request to peer.
            err_code = icmp6_echo_request(p_interface, &src_ipv6_addr, &dest_ipv6_addr, p_buffer);
            APP_ERROR_CHECK(err_code);

            err_code = app_timer_start(m_tx_node_timer, APP_PING_INTERVAL, NULL);
            APP_ERROR_CHECK(err_code);

            break;
        }
        case APP_STATE_PEER_REACHABLE:
        {
            uint32_t ind_buff = 0;
            err_code = get_packet_buffer_index(&ind_buff, (uint32_t *)&m_invalid_pkt_seq_num);
            if (err_code == NRF_ERROR_NOT_FOUND)
            {
                // Buffer of expected packets full, checking if peer is reachable.
                APPL_LOG("[APPL]: %ld packets transmitted, %d packets lost. Resetting counter. \r\n", \
                             m_pkt_seq_num, PACKET_BUFFER_LEN);
                m_node_state    = APP_STATE_IPV6_IF_UP;
                m_display_state = LEDS_TX_ECHO_REQUEST;
                m_pkt_seq_num = 0;
                memset(&m_packet_buffer[0][0], 0x00, sizeof(m_packet_buffer));
                err_code = app_timer_start(m_tx_node_timer, APP_PING_INTERVAL, NULL);
                APP_ERROR_CHECK(err_code);
                return;
            }

            ++m_pkt_seq_num;
            if (m_pkt_seq_num == INVALID_PACKET_SEQ_NUMBER)
            {
                ++m_pkt_seq_num;
            }

            test_packet_payload_t packet;
            uint8_t encoded_seq_num[TEST_PACKET_NUM_LEN];
            UNUSED_VARIABLE(uint32_encode(m_pkt_seq_num, &encoded_seq_num[0]));
            // The first 4 bytes of the payload is the packet sequence number.
            memcpy(&packet.packet_seq_num[0], &encoded_seq_num[0], TEST_PACKET_NUM_LEN);
            // The rest of the payload is random bytes.
            do
            {
                err_code = sd_rand_application_vector_get(&packet.packet_data[0], \
                                                          sizeof(packet.packet_data));
            }
            while (err_code == NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES);
            APP_ERROR_CHECK(err_code);

            iot_pbuffer_alloc_param_t   pbuff_param;
            iot_pbuffer_t             * p_buffer;

            pbuff_param.flags  = PBUFFER_FLAG_DEFAULT;
            pbuff_param.type   = UDP6_PACKET_TYPE;
            pbuff_param.length = TEST_PACKET_PAYLOAD_LEN;

            // Allocate packet buffer.
            err_code = iot_pbuffer_allocate(&pbuff_param, &p_buffer);
            APP_ERROR_CHECK(err_code);

            memcpy(p_buffer->p_payload, &packet.packet_seq_num[0], TEST_PACKET_NUM_LEN);
            memcpy(p_buffer->p_payload+TEST_PACKET_NUM_LEN, &packet.packet_data[0], TEST_PACKET_DATA_LEN);

            ipv6_addr_t dest_ipv6_addr;
            memset(&dest_ipv6_addr, 0x00, sizeof(ipv6_addr_t));
            memcpy(&dest_ipv6_addr.u8[0], (uint8_t[]){SERVER_IPV6_ADDRESS}, IPV6_ADDR_SIZE);

            // Transmit UDP6 packet.
            err_code = udp6_socket_sendto(&m_udp_socket, &dest_ipv6_addr, HTONS(UDP_PORT), p_buffer);
            APP_ERROR_CHECK(err_code);

            APPL_LOG("[APPL]: Transmitted UDP packet sequence number: %ld\r\n", m_pkt_seq_num);

            // Store sent packet amongst expected packets.
            memcpy(&m_packet_buffer[ind_buff][0], &packet.packet_seq_num[0], TEST_PACKET_NUM_LEN);
            memcpy(&m_packet_buffer[ind_buff][TEST_PACKET_NUM_LEN], &packet.packet_data[0], TEST_PACKET_DATA_LEN);

            if (m_pkt_seq_num == 1)
            {
                err_code = app_timer_start(m_tx_node_timer, (TX_INTERVAL*5), NULL); // Slow start.
                APP_ERROR_CHECK(err_code);
            }
            else
            {
                err_code = app_timer_start(m_tx_node_timer, TX_INTERVAL, NULL);
                APP_ERROR_CHECK(err_code);
            }

            break;
        }
        default:
        {
            break;
        }
    }
}