| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617 |
- /*********************************************************************
- * _ _ _
- * _ __ | |_ _ | | __ _ | |__ ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | | | |_ _ | || (_| || |_) |\__ \
- * |_| \__|(_)|_| \__,_||_.__/ |___/
- *
- * 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);
- }
- }
- }
|