618 lines
18 KiB
C++
618 lines
18 KiB
C++
/*********************************************************************
|
|
* _ _ _
|
|
* _ __ | |_ _ | | __ _ | |__ ___
|
|
* | '__|| __|(_)| | / _` || '_ \ / __|
|
|
* | | | |_ _ | || (_| || |_) |\__ \
|
|
* |_| \__|(_)|_| \__,_||_.__/ |___/
|
|
*
|
|
* www.rt-labs.com
|
|
* Copyright 2018 rt-labs AB, Sweden.
|
|
*
|
|
* This software is dual-licensed under GPLv3 and a commercial
|
|
* license. See the file LICENSE.md distributed with this software for
|
|
* full license information.
|
|
********************************************************************/
|
|
|
|
#include "utils_for_testing.h"
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
/******************** Callbacks defined by p-net *****************************/
|
|
|
|
int my_connect_ind (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t arep,
|
|
pnet_result_t * p_result)
|
|
{
|
|
app_data_for_testing_t * p_appdata = (app_data_for_testing_t *)arg;
|
|
|
|
p_appdata->call_counters.connect_calls++;
|
|
return 0;
|
|
}
|
|
|
|
int my_release_ind (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t arep,
|
|
pnet_result_t * p_result)
|
|
{
|
|
app_data_for_testing_t * p_appdata = (app_data_for_testing_t *)arg;
|
|
|
|
p_appdata->call_counters.release_calls++;
|
|
return 0;
|
|
}
|
|
|
|
int my_dcontrol_ind (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t arep,
|
|
pnet_control_command_t control_command,
|
|
pnet_result_t * p_result)
|
|
{
|
|
app_data_for_testing_t * p_appdata = (app_data_for_testing_t *)arg;
|
|
|
|
p_appdata->call_counters.dcontrol_calls++;
|
|
return 0;
|
|
}
|
|
|
|
int my_ccontrol_cnf (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t arep,
|
|
pnet_result_t * p_result)
|
|
{
|
|
app_data_for_testing_t * p_appdata = (app_data_for_testing_t *)arg;
|
|
|
|
p_appdata->call_counters.ccontrol_calls++;
|
|
return 0;
|
|
}
|
|
|
|
static int my_signal_led_ind (pnet_t * net, void * arg, bool led_state)
|
|
{
|
|
app_data_for_testing_t * p_appdata = (app_data_for_testing_t *)arg;
|
|
|
|
TEST_TRACE ("Callback on set LED state: %u\n", led_state);
|
|
if (led_state == 1)
|
|
{
|
|
p_appdata->call_counters.led_on_calls++;
|
|
}
|
|
else
|
|
{
|
|
p_appdata->call_counters.led_off_calls++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int my_read_ind (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t arep,
|
|
uint32_t api,
|
|
uint16_t slot,
|
|
uint16_t subslot,
|
|
uint16_t idx,
|
|
uint16_t sequence_number,
|
|
uint8_t ** pp_read_data, /* Out: A pointer to the data */
|
|
uint16_t * p_read_length, /* Out: Size of data */
|
|
pnet_result_t * p_result) /* Error status if returning != 0 */
|
|
{
|
|
app_data_for_testing_t * p_appdata = (app_data_for_testing_t *)arg;
|
|
|
|
TEST_TRACE ("Callback on read\n");
|
|
TEST_TRACE (
|
|
" API: %" PRIu32 " Slot: %" PRIu16 " Subslot: %" PRIu16
|
|
" Index: %" PRIu16 " Sequence: %" PRIu16 "\n",
|
|
api,
|
|
slot,
|
|
subslot,
|
|
idx,
|
|
sequence_number);
|
|
p_appdata->call_counters.read_calls++;
|
|
return 0;
|
|
}
|
|
|
|
int my_write_ind (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t arep,
|
|
uint32_t api,
|
|
uint16_t slot,
|
|
uint16_t subslot,
|
|
uint16_t idx,
|
|
uint16_t sequence_number,
|
|
uint16_t write_length,
|
|
const uint8_t * p_write_data,
|
|
pnet_result_t * p_result)
|
|
{
|
|
app_data_for_testing_t * p_appdata = (app_data_for_testing_t *)arg;
|
|
|
|
TEST_TRACE ("Callback on write\n");
|
|
TEST_TRACE (
|
|
" API: %" PRIu32 " Slot: %" PRIu16 " Subslot: %" PRIu16
|
|
" Index: %" PRIu16 " Sequence: %" PRIu16 " Len: %" PRIu16 "\n",
|
|
api,
|
|
slot,
|
|
subslot,
|
|
idx,
|
|
sequence_number,
|
|
write_length);
|
|
p_appdata->call_counters.write_calls++;
|
|
return 0;
|
|
}
|
|
|
|
int my_new_data_status_ind (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t arep,
|
|
uint32_t crep,
|
|
uint8_t changes,
|
|
uint8_t data_status)
|
|
{
|
|
TEST_TRACE ("Callback on new data\n");
|
|
return 0;
|
|
}
|
|
|
|
int my_alarm_ind (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t arep,
|
|
const pnet_alarm_argument_t * p_alarm_arg,
|
|
uint16_t data_len,
|
|
uint16_t data_usi,
|
|
const uint8_t * p_data)
|
|
{
|
|
TEST_TRACE ("Callback on alarm\n");
|
|
return 0;
|
|
}
|
|
|
|
int my_alarm_cnf (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t arep,
|
|
const pnet_pnio_status_t * p_pnio_status)
|
|
{
|
|
TEST_TRACE ("Callback on alarm confirmation\n");
|
|
return 0;
|
|
}
|
|
|
|
int my_state_ind (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t arep,
|
|
pnet_event_values_t state)
|
|
{
|
|
app_data_for_testing_t * p_appdata = (app_data_for_testing_t *)arg;
|
|
int ret;
|
|
uint16_t slot = 0;
|
|
uint16_t err_cls = 0;
|
|
uint16_t err_code = 0;
|
|
|
|
p_appdata->call_counters.state_calls++;
|
|
p_appdata->main_arep = arep;
|
|
p_appdata->cmdev_state = state;
|
|
|
|
if (state == PNET_EVENT_PRMEND)
|
|
{
|
|
/* Set IOPS for DAP slot (has same numbering as the module identifiers) */
|
|
ret = pnet_input_set_data_and_iops (
|
|
net,
|
|
TEST_API_IDENT,
|
|
PNET_SLOT_DAP_IDENT,
|
|
PNET_SUBSLOT_DAP_IDENT,
|
|
NULL,
|
|
0,
|
|
PNET_IOXS_GOOD);
|
|
EXPECT_EQ (ret, 0);
|
|
ret = pnet_input_set_data_and_iops (
|
|
net,
|
|
TEST_API_IDENT,
|
|
PNET_SLOT_DAP_IDENT,
|
|
PNET_SUBSLOT_DAP_INTERFACE_1_IDENT,
|
|
NULL,
|
|
0,
|
|
PNET_IOXS_GOOD);
|
|
EXPECT_EQ (ret, 0);
|
|
ret = pnet_input_set_data_and_iops (
|
|
net,
|
|
TEST_API_IDENT,
|
|
PNET_SLOT_DAP_IDENT,
|
|
PNET_SUBSLOT_DAP_INTERFACE_1_PORT_1_IDENT,
|
|
NULL,
|
|
0,
|
|
PNET_IOXS_GOOD);
|
|
EXPECT_EQ (ret, 0);
|
|
|
|
/* Set initial data and IOPS for custom input modules, and IOCS for custom
|
|
* output modules */
|
|
for (slot = 0; slot < PNET_MAX_SLOTS; slot++)
|
|
{
|
|
if (p_appdata->custom_input_slots[slot] == true)
|
|
{
|
|
ret = pnet_input_set_data_and_iops (
|
|
net,
|
|
TEST_API_IDENT,
|
|
slot,
|
|
TEST_SUBMOD_CUSTOM_IDENT,
|
|
p_appdata->inputdata,
|
|
TEST_DATASIZE_INPUT,
|
|
PNET_IOXS_GOOD);
|
|
EXPECT_EQ (ret, 0);
|
|
}
|
|
if (p_appdata->custom_output_slots[slot] == true)
|
|
{
|
|
ret = pnet_output_set_iocs (
|
|
net,
|
|
TEST_API_IDENT,
|
|
slot,
|
|
TEST_SUBMOD_CUSTOM_IDENT,
|
|
PNET_IOXS_GOOD);
|
|
EXPECT_EQ (ret, 0);
|
|
}
|
|
}
|
|
|
|
ret = pnet_set_provider_state (net, true);
|
|
EXPECT_EQ (ret, 0);
|
|
}
|
|
else if (state == PNET_EVENT_ABORT)
|
|
{
|
|
ret = pnet_get_ar_error_codes (net, arep, &err_cls, &err_code);
|
|
EXPECT_EQ (ret, 0);
|
|
TEST_TRACE (
|
|
"ABORT err_cls 0x%02" PRIx16 " err_code 0x%02" PRIx16 "\n",
|
|
err_cls,
|
|
err_code);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int my_exp_module_ind (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t api,
|
|
uint16_t slot,
|
|
uint32_t module_ident)
|
|
{
|
|
app_data_for_testing_t * p_appdata = (app_data_for_testing_t *)arg;
|
|
int ret = -1; /* Not supported in specified slot */
|
|
bool found = false;
|
|
uint16_t ix;
|
|
|
|
TEST_TRACE ("Callback on module\n");
|
|
|
|
/* Find it in the list of supported modules */
|
|
ix = 0;
|
|
while (ix < TEST_MAX_NUMBER_AVAILABLE_MODULE_TYPES)
|
|
{
|
|
if (p_appdata->available_module_types[ix] == module_ident)
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
ix++;
|
|
}
|
|
|
|
if (found == true)
|
|
{
|
|
/* For now support any module in any slot */
|
|
TEST_TRACE (
|
|
" Plug module. API: %" PRIu32 " Slot: %" PRIu16 " Module ID: "
|
|
"%" PRIu32 " Index in list of supported modules: %" PRIu16 "\n",
|
|
api,
|
|
slot,
|
|
module_ident,
|
|
ix);
|
|
ret = pnet_plug_module (net, api, slot, module_ident);
|
|
EXPECT_EQ (ret, 0);
|
|
|
|
/* Remember what is plugged in each slot */
|
|
if (module_ident == TEST_MOD_8_0_IDENT || module_ident == TEST_MOD_8_8_IDENT)
|
|
{
|
|
p_appdata->custom_input_slots[slot] = true;
|
|
}
|
|
if (module_ident == TEST_MOD_8_8_IDENT || module_ident == TEST_MOD_0_8_IDENT)
|
|
{
|
|
p_appdata->custom_output_slots[slot] = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TEST_TRACE (" Module ident %08" PRIx32 " not found\n", module_ident);
|
|
EXPECT_TRUE (false); // Fail the test
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int my_exp_submodule_ind (
|
|
pnet_t * net,
|
|
void * arg,
|
|
uint32_t api,
|
|
uint16_t slot,
|
|
uint16_t subslot,
|
|
uint32_t module_ident,
|
|
uint32_t submodule_ident,
|
|
const pnet_data_cfg_t * p_exp_data)
|
|
{
|
|
app_data_for_testing_t * p_appdata = (app_data_for_testing_t *)arg;
|
|
int ret = -1;
|
|
bool found = false;
|
|
uint16_t ix = 0;
|
|
|
|
TEST_TRACE ("Callback on submodule\n");
|
|
|
|
/* Find it in the list of supported submodules */
|
|
ix = 0;
|
|
while (ix < TEST_MAX_NUMBER_AVAILABLE_SUBMODULE_TYPES)
|
|
{
|
|
if (
|
|
p_appdata->available_submodule_types[ix].module_ident_number ==
|
|
module_ident &&
|
|
p_appdata->available_submodule_types[ix].submodule_ident_number ==
|
|
submodule_ident)
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
ix++;
|
|
}
|
|
|
|
if (found == true)
|
|
{
|
|
TEST_TRACE (
|
|
" Plug submodule. API: %" PRIu32 " Slot: %" PRIu16 " Subslot: "
|
|
"%" PRIu16 " Module ID: %" PRIu32 " Submodule ID: %" PRIu32
|
|
" (Index in "
|
|
"available "
|
|
"submodules: %" PRIu16 ") Direction: %u Len in: %" PRIu16
|
|
" out: %" PRIu16 "\n",
|
|
api,
|
|
slot,
|
|
subslot,
|
|
module_ident,
|
|
submodule_ident,
|
|
ix,
|
|
p_appdata->available_submodule_types[ix].direction,
|
|
p_appdata->available_submodule_types[ix].input_length,
|
|
p_appdata->available_submodule_types[ix].output_length);
|
|
ret = pnet_plug_submodule (
|
|
net,
|
|
api,
|
|
slot,
|
|
subslot,
|
|
module_ident,
|
|
submodule_ident,
|
|
p_appdata->available_submodule_types[ix].direction,
|
|
p_appdata->available_submodule_types[ix].input_length,
|
|
p_appdata->available_submodule_types[ix].output_length);
|
|
EXPECT_EQ (ret, 0);
|
|
}
|
|
else
|
|
{
|
|
TEST_TRACE (
|
|
" Sub-module ident %08" PRIx32 " not found\n",
|
|
submodule_ident);
|
|
EXPECT_TRUE (false); // Fail the test
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*********************** Base classes for tests *****************************/
|
|
|
|
void PnetIntegrationTestBase::appdata_init()
|
|
{
|
|
memset (&appdata, 0, sizeof (appdata));
|
|
}
|
|
|
|
void PnetIntegrationTestBase::callcounter_reset()
|
|
{
|
|
memset (&appdata.call_counters, 0, sizeof (call_counters_t));
|
|
}
|
|
|
|
void PnetIntegrationTestBase::available_modules_and_submodules_init()
|
|
{
|
|
appdata.available_module_types[0] = PNET_MOD_DAP_IDENT;
|
|
appdata.available_module_types[1] = TEST_MOD_8_8_IDENT;
|
|
appdata.available_module_types[2] = TEST_MOD_8_0_IDENT;
|
|
|
|
appdata.available_submodule_types[0].module_ident_number =
|
|
PNET_MOD_DAP_IDENT;
|
|
appdata.available_submodule_types[0].submodule_ident_number =
|
|
PNET_SUBMOD_DAP_IDENT;
|
|
appdata.available_submodule_types[0].direction = PNET_DIR_NO_IO;
|
|
appdata.available_submodule_types[0].input_length = 0;
|
|
appdata.available_submodule_types[0].output_length = 0;
|
|
|
|
appdata.available_submodule_types[1].module_ident_number =
|
|
PNET_MOD_DAP_IDENT;
|
|
appdata.available_submodule_types[1].submodule_ident_number =
|
|
PNET_SUBMOD_DAP_INTERFACE_1_IDENT;
|
|
appdata.available_submodule_types[1].direction = PNET_DIR_NO_IO;
|
|
appdata.available_submodule_types[1].input_length = 0;
|
|
appdata.available_submodule_types[1].output_length = 0;
|
|
|
|
appdata.available_submodule_types[2].module_ident_number =
|
|
PNET_MOD_DAP_IDENT;
|
|
appdata.available_submodule_types[2].submodule_ident_number =
|
|
PNET_SUBMOD_DAP_INTERFACE_1_PORT_1_IDENT;
|
|
appdata.available_submodule_types[2].direction = PNET_DIR_NO_IO;
|
|
appdata.available_submodule_types[2].input_length = 0;
|
|
appdata.available_submodule_types[2].output_length = 0;
|
|
|
|
appdata.available_submodule_types[3].module_ident_number =
|
|
TEST_MOD_8_8_IDENT;
|
|
appdata.available_submodule_types[3].submodule_ident_number =
|
|
TEST_SUBMOD_CUSTOM_IDENT;
|
|
appdata.available_submodule_types[3].direction = PNET_DIR_IO;
|
|
appdata.available_submodule_types[3].input_length = TEST_DATASIZE_INPUT;
|
|
appdata.available_submodule_types[3].output_length = TEST_DATASIZE_OUTPUT;
|
|
|
|
appdata.available_submodule_types[4].module_ident_number =
|
|
TEST_MOD_8_0_IDENT;
|
|
appdata.available_submodule_types[4].submodule_ident_number =
|
|
TEST_SUBMOD_CUSTOM_IDENT;
|
|
appdata.available_submodule_types[4].direction = PNET_DIR_OUTPUT;
|
|
appdata.available_submodule_types[4].input_length = 0;
|
|
appdata.available_submodule_types[4].output_length = TEST_DATASIZE_OUTPUT;
|
|
}
|
|
|
|
void PnetIntegrationTestBase::cfg_init()
|
|
{
|
|
pnet_default_cfg.tick_us = TEST_TICK_INTERVAL_US;
|
|
pnet_default_cfg.state_cb = my_state_ind;
|
|
pnet_default_cfg.connect_cb = my_connect_ind;
|
|
pnet_default_cfg.release_cb = my_release_ind;
|
|
pnet_default_cfg.dcontrol_cb = my_dcontrol_ind;
|
|
pnet_default_cfg.ccontrol_cb = my_ccontrol_cnf;
|
|
pnet_default_cfg.read_cb = my_read_ind;
|
|
pnet_default_cfg.write_cb = my_write_ind;
|
|
pnet_default_cfg.exp_module_cb = my_exp_module_ind;
|
|
pnet_default_cfg.exp_submodule_cb = my_exp_submodule_ind;
|
|
pnet_default_cfg.new_data_status_cb = my_new_data_status_ind;
|
|
pnet_default_cfg.alarm_ind_cb = my_alarm_ind;
|
|
pnet_default_cfg.alarm_cnf_cb = my_alarm_cnf;
|
|
pnet_default_cfg.signal_led_cb = my_signal_led_ind;
|
|
pnet_default_cfg.reset_cb = NULL;
|
|
pnet_default_cfg.cb_arg = &appdata;
|
|
|
|
/* Device configuration */
|
|
pnet_default_cfg.device_id.vendor_id_hi = 0xfe;
|
|
pnet_default_cfg.device_id.vendor_id_lo = 0xed;
|
|
pnet_default_cfg.device_id.device_id_hi = 0xbe;
|
|
pnet_default_cfg.device_id.device_id_lo = 0xef;
|
|
pnet_default_cfg.oem_device_id.vendor_id_hi = 0xfe;
|
|
pnet_default_cfg.oem_device_id.vendor_id_lo = 0xed;
|
|
pnet_default_cfg.oem_device_id.device_id_hi = 0xbe;
|
|
pnet_default_cfg.oem_device_id.device_id_lo = 0xef;
|
|
|
|
strcpy (pnet_default_cfg.station_name, "");
|
|
strcpy (pnet_default_cfg.product_name, "PNET unit tests");
|
|
|
|
pnet_default_cfg.if_cfg.physical_ports[0].netif_name = TEST_INTERFACE_NAME;
|
|
|
|
/* Timing */
|
|
pnet_default_cfg.min_device_interval = 32; /* Corresponds to 1 ms */
|
|
|
|
/* Network configuration */
|
|
pnet_default_cfg.send_hello = 1; /* Send HELLO */
|
|
pnet_default_cfg.if_cfg.ip_cfg.dhcp_enable = 0;
|
|
pnet_default_cfg.if_cfg.main_netif_name = TEST_INTERFACE_NAME;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_addr.a = 192;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_addr.b = 168;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_addr.c = 1;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_addr.d = 171;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_mask.a = 255;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_mask.b = 255;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_mask.c = 255;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_mask.d = 255;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_gateway.a = 192;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_gateway.b = 168;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_gateway.c = 1;
|
|
pnet_default_cfg.if_cfg.ip_cfg.ip_gateway.d = 1;
|
|
|
|
pnet_default_cfg.im_0_data.im_vendor_id_hi = 0x00;
|
|
pnet_default_cfg.im_0_data.im_vendor_id_lo = 0x01;
|
|
strcpy (pnet_default_cfg.im_0_data.im_order_id, "<orderid> ");
|
|
strcpy (pnet_default_cfg.im_0_data.im_serial_number, "<serial nbr> ");
|
|
pnet_default_cfg.im_0_data.im_hardware_revision = 1;
|
|
pnet_default_cfg.im_0_data.im_sw_revision_prefix = 'P'; /* 'V', 'R', 'P',
|
|
'U', or 'T' */
|
|
pnet_default_cfg.im_0_data.im_sw_revision_functional_enhancement = 0;
|
|
pnet_default_cfg.im_0_data.im_sw_revision_bug_fix = 0;
|
|
pnet_default_cfg.im_0_data.im_sw_revision_internal_change = 0;
|
|
pnet_default_cfg.im_0_data.im_revision_counter = 0;
|
|
pnet_default_cfg.im_0_data.im_profile_id = 0x1234;
|
|
pnet_default_cfg.im_0_data.im_profile_specific_type = 0x5678;
|
|
pnet_default_cfg.im_0_data.im_version_major = 0;
|
|
pnet_default_cfg.im_0_data.im_version_minor = 1;
|
|
pnet_default_cfg.im_0_data.im_supported =
|
|
PNET_SUPPORTED_IM1 | PNET_SUPPORTED_IM2 | PNET_SUPPORTED_IM3 |
|
|
PNET_SUPPORTED_IM4;
|
|
strcpy (pnet_default_cfg.im_1_data.im_tag_function, "");
|
|
strcpy (pnet_default_cfg.im_1_data.im_tag_location, "");
|
|
strcpy (pnet_default_cfg.im_2_data.im_date, "");
|
|
strcpy (pnet_default_cfg.im_3_data.im_descriptor, "");
|
|
strcpy (pnet_default_cfg.im_4_data.im_signature, "");
|
|
|
|
/* Storage */
|
|
strcpy (pnet_default_cfg.file_directory, "/disk1");
|
|
|
|
/* Diagnosis */
|
|
pnet_default_cfg.use_qualified_diagnosis = true;
|
|
|
|
pnet_default_cfg.num_physical_ports = PNET_MAX_PHYSICAL_PORTS;
|
|
}
|
|
|
|
void PnetIntegrationTestBase::run_stack (int us)
|
|
{
|
|
uint16_t slot = 0;
|
|
|
|
for (int tmr = 0; tmr < us / TEST_TICK_INTERVAL_US; tmr++)
|
|
{
|
|
/* Set new output data every 10 ticks */
|
|
appdata.tick_ctr++;
|
|
if ((appdata.main_arep != 0) && (appdata.tick_ctr > 10))
|
|
{
|
|
appdata.tick_ctr = 0;
|
|
appdata.inputdata[0] = appdata.counter_data++;
|
|
|
|
/* Set data for custom input modules, if any */
|
|
for (slot = 0; slot < PNET_MAX_SLOTS; slot++)
|
|
{
|
|
if (appdata.custom_input_slots[slot] == true)
|
|
{
|
|
(void)pnet_input_set_data_and_iops (
|
|
net,
|
|
TEST_API_IDENT,
|
|
slot,
|
|
TEST_SUBMOD_CUSTOM_IDENT,
|
|
appdata.inputdata,
|
|
TEST_DATASIZE_INPUT,
|
|
PNET_IOXS_GOOD);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Run stack functionality every tick */
|
|
pnet_handle_periodic (net);
|
|
mock_os_data.current_time_us += TEST_TICK_INTERVAL_US;
|
|
}
|
|
}
|
|
|
|
void PnetIntegrationTestBase::send_data (uint8_t * data_packet, uint16_t len)
|
|
{
|
|
int ret;
|
|
pnal_buf_t * p_buf;
|
|
uint8_t * p_ctr;
|
|
|
|
p_buf = pnal_buf_alloc (PF_FRAME_BUFFER_SIZE);
|
|
if (p_buf == NULL)
|
|
{
|
|
TEST_TRACE ("(%d): Out of memory in send_data\n", __LINE__);
|
|
}
|
|
else
|
|
{
|
|
memcpy (p_buf->payload, data_packet, len);
|
|
|
|
/* Insert frame time, store in big-endian */
|
|
appdata.data_cycle_ctr++;
|
|
p_ctr = &((uint8_t *)(p_buf->payload))[len - 4];
|
|
*(p_ctr + 0) = (appdata.data_cycle_ctr >> 8) & 0xff;
|
|
*(p_ctr + 1) = appdata.data_cycle_ctr & 0xff;
|
|
|
|
p_buf->len = len;
|
|
ret = pf_eth_recv (mock_os_data.eth_if_handle, net, p_buf);
|
|
EXPECT_EQ (ret, 1);
|
|
if (ret == 0)
|
|
{
|
|
TEST_TRACE ("(%d): Unhandled p_buf\n", __LINE__);
|
|
pnal_buf_free (p_buf);
|
|
}
|
|
}
|
|
}
|