mirror of https://github.com/ARMmbed/mbed-os.git
Tests for wifi emac interface
parent
a519b8449b
commit
5c15819130
|
@ -0,0 +1,28 @@
|
|||
# Description
|
||||
|
||||
This document describes how to run EMAC tests. The EMAC test cases are made using Ethernet Configuration Testing Protocol (CTP). To run the tests, one device in the Ethernet segment needs to be configured to be a CTP echo server. The devices running the test cases, use the echo server to forward the CTP Ethernet frames back.
|
||||
|
||||
# Configuring CTP echo server
|
||||
|
||||
A device can be configured to be a CTP echo server by enabling `echo-server` setting in the test environment's application `json` file. When device is configured to be a CTP echo server, it starts to forward CTP messages automatically after power up and will continue forwarding until power down.
|
||||
|
||||
# Test cases
|
||||
|
||||
## EMAC interface initialise
|
||||
|
||||
Initializes EMAC interface driver.
|
||||
|
||||
For WLAN installs test case so that it can intercept incoming Ethernet messages from the WLAN driver. Incoming CTP frames are handed by the test case and other frames are forwarded to the LWIP stack.
|
||||
|
||||
## EMAC interface broadcast
|
||||
|
||||
Sends three 100 byte CTP broadcast messages, waits for three seconds and sends three 50 byte CTP broadcast messages. Listens for the CTP echo server responses and stores the addresses of the echo servers if replies are received. The test case will pass if there are no responses from echo server, but further test cases will be skipped.
|
||||
|
||||
## EMAC interface unicast
|
||||
|
||||
Sends three CTP unicast messages to the CTP echo server. Verifies that all are replied.
|
||||
|
||||
## EMAC interface unicast frame length
|
||||
|
||||
Sends CTP unicast messages with Ethernet message length from 100 bytes to maximum. Verifies that all are replied.
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#if MBED_CONF_APP_TEST_WIFI || MBED_CONF_APP_TEST_ETHERNET
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
#include "lwip/opt.h" /* ETH_PAD_SIZE */
|
||||
|
||||
#include "emac_stack_mem.h"
|
||||
#include "emac_api.h"
|
||||
|
||||
#include "emac_tests.h"
|
||||
#include "emac_ctp.h"
|
||||
|
||||
#include "emac_initialize.h"
|
||||
#include "emac_util.h"
|
||||
#include "emac_membuf.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
// Unique identifier for message
|
||||
static int receipt_number = 0;
|
||||
|
||||
static int emac_if_ctp_header_build(unsigned char *eth_frame, const unsigned char *dest_addr, const unsigned char *origin_addr, const unsigned char *forward_addr)
|
||||
{
|
||||
memcpy(ð_frame[0], dest_addr, 6);
|
||||
memcpy(ð_frame[6], origin_addr, 6);
|
||||
|
||||
eth_frame[12] = 0x90; /* loop back */
|
||||
eth_frame[13] = 0x00;
|
||||
|
||||
eth_frame[14] = 0x00; /* skip count */
|
||||
eth_frame[15] = 0x00;
|
||||
|
||||
eth_frame[16] = 0x02; /* function, forward */
|
||||
eth_frame[17] = 0x00;
|
||||
|
||||
memcpy(ð_frame[18], forward_addr, 6);
|
||||
|
||||
eth_frame[24] = 0x01; /* function, reply */
|
||||
eth_frame[25] = 0x00;
|
||||
|
||||
receipt_number++;
|
||||
|
||||
eth_frame[26] = receipt_number; /* receipt number */
|
||||
eth_frame[27] = receipt_number >> 8;
|
||||
|
||||
return receipt_number;
|
||||
}
|
||||
|
||||
ctp_function emac_if_ctp_header_handle(unsigned char *eth_input_frame, unsigned char *eth_output_frame, unsigned char *origin_addr, int *receipt_number)
|
||||
{
|
||||
if (eth_input_frame[12] != 0x90 || eth_input_frame[13] != 0x00) {
|
||||
return CTP_NONE;
|
||||
}
|
||||
|
||||
int skip_count = eth_input_frame[15] << 8 | eth_input_frame[14];
|
||||
unsigned char *ethernet_ptr = ð_input_frame[16] + skip_count;
|
||||
|
||||
int function = ethernet_ptr[1] << 8 | ethernet_ptr[0];
|
||||
ethernet_ptr += 2;
|
||||
|
||||
// Forward
|
||||
if (function == 0x0002) {
|
||||
memcpy(eth_output_frame, eth_input_frame, ETH_FRAME_HEADER_LEN);
|
||||
// Update skip count
|
||||
skip_count += 8;
|
||||
eth_output_frame[14] = skip_count;
|
||||
eth_output_frame[15] = skip_count >> 8;
|
||||
// Set forward address to destination address
|
||||
memcpy(ð_output_frame[0], ethernet_ptr, 6);
|
||||
// Copy own address to origin
|
||||
memcpy(ð_output_frame[6], origin_addr, 6);
|
||||
return CTP_FORWARD;
|
||||
// reply
|
||||
} else if (function == 0x0001) {
|
||||
*receipt_number = ethernet_ptr[1] << 8 | ethernet_ptr[0];
|
||||
return CTP_REPLY;
|
||||
}
|
||||
|
||||
return CTP_NONE;
|
||||
}
|
||||
|
||||
void emac_if_ctp_msg_build(int eth_frame_len, const unsigned char *dest_addr, const unsigned char *origin_addr, const unsigned char *forward_addr)
|
||||
{
|
||||
if (eth_frame_len < ETH_FRAME_HEADER_LEN) {
|
||||
eth_frame_len = ETH_FRAME_HEADER_LEN;
|
||||
}
|
||||
|
||||
printf("message sent %x:%x:%x:%x:%x:%x\r\n\r\n", dest_addr[0], dest_addr[1], dest_addr[2], dest_addr[3], dest_addr[4], dest_addr[5]);
|
||||
|
||||
int outgoing_msg_index = emac_if_add_outgoing_msg(eth_frame_len);
|
||||
|
||||
if (outgoing_msg_index < 0) {
|
||||
SET_ERROR_FLAGS(OUT_OF_MSG_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
emac_stack_mem_chain_t *mem_chain_p = emac_stack_mem_alloc(0, eth_frame_len + ETH_PAD_SIZE, 0);
|
||||
|
||||
if (!mem_chain_p) {
|
||||
SET_ERROR_FLAGS(NO_FREE_MEM_BUF);
|
||||
emac_if_free_outgoing_msg(outgoing_msg_index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp(dest_addr, eth_mac_broadcast_addr, 6) == 0) {
|
||||
emac_if_set_outgoing_msg_flags(outgoing_msg_index, BROADCAST);
|
||||
}
|
||||
|
||||
unsigned char eth_output_frame_data[ETH_FRAME_HEADER_LEN];
|
||||
int receipt_number = emac_if_ctp_header_build(eth_output_frame_data, dest_addr, origin_addr, forward_addr);
|
||||
emac_if_set_outgoing_msg_receipt_num(outgoing_msg_index, receipt_number);
|
||||
|
||||
emac_if_memory_buffer_write(mem_chain_p, eth_output_frame_data, true);
|
||||
|
||||
//emac_if->ops.link_out(hw_driver, mem_chain_p);
|
||||
emac_if_get()->ops.link_out(emac_if_get(), mem_chain_p);
|
||||
|
||||
emac_stack_mem_free(0, mem_chain_p);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EMAC_CTP_H
|
||||
#define EMAC_CTP_H
|
||||
|
||||
enum ctp_function {
|
||||
CTP_NONE,
|
||||
CTP_FORWARD,
|
||||
CTP_REPLY
|
||||
};
|
||||
|
||||
ctp_function emac_if_ctp_header_handle(unsigned char *eth_input_frame, unsigned char *eth_output_frame, unsigned char *origin_addr, int *receipt_number);
|
||||
void emac_if_ctp_msg_build(int eth_frame_len, const unsigned char *dest_addr, const unsigned char *origin_addr, const unsigned char *forward_addr);
|
||||
void emac_if_ctp_reply_handle(int lenght, int invalid_data_index);
|
||||
|
||||
#endif /* EMAC_CTP_H */
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EMAC_INITIALIZE_H
|
||||
#define EMAC_INITIALIZE_H
|
||||
|
||||
uint8_t *emac_if_get_hw_addr(void);
|
||||
emac_interface_t *emac_if_get(void);
|
||||
|
||||
#endif /* EMAC_INITIALIZE_H */
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#if MBED_CONF_APP_TEST_WIFI || MBED_CONF_APP_TEST_ETHERNET
|
||||
|
||||
#include "lwip/opt.h" /* ETH_PAD_SIZE */
|
||||
|
||||
#include "emac_api.h"
|
||||
#include "emac_stack_mem.h"
|
||||
|
||||
#include "emac_membuf.h"
|
||||
#include "emac_util.h"
|
||||
|
||||
int emac_if_memory_buffer_read(emac_stack_mem_chain_t *mem_chain_p, unsigned char *eth_frame)
|
||||
{
|
||||
int eth_frame_index = 0;
|
||||
int invalid_data_index = 0;
|
||||
int index = ETH_PAD_SIZE;
|
||||
|
||||
for (emac_stack_mem_t *mem_p = emac_stack_mem_chain_dequeue(0, &mem_chain_p); mem_p != NULL; mem_p = emac_stack_mem_chain_dequeue(0, &mem_chain_p)) {
|
||||
unsigned char *buf_payload = (unsigned char *) emac_stack_mem_ptr(0, mem_p);
|
||||
int buf_payload_len = emac_stack_mem_len(0, mem_p);
|
||||
|
||||
for (; index < buf_payload_len; index++) {
|
||||
if (eth_frame_index < ETH_FRAME_HEADER_LEN) {
|
||||
eth_frame[eth_frame_index] = buf_payload[index];
|
||||
} else {
|
||||
if (buf_payload[index] != (uint8_t) eth_frame_index) {
|
||||
invalid_data_index = eth_frame_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
eth_frame_index++;
|
||||
}
|
||||
index = 0;
|
||||
}
|
||||
|
||||
return invalid_data_index;
|
||||
}
|
||||
|
||||
void emac_if_memory_buffer_write(emac_stack_mem_chain_t *mem_chain_p, unsigned char *eth_frame, bool write_data)
|
||||
{
|
||||
int eth_frame_index = 0;
|
||||
int index = ETH_PAD_SIZE;
|
||||
|
||||
for (emac_stack_mem_t *mem_p = emac_stack_mem_chain_dequeue(0, &mem_chain_p); mem_p != NULL; mem_p = emac_stack_mem_chain_dequeue(0, &mem_chain_p)) {
|
||||
unsigned char *buf_payload = (unsigned char *) emac_stack_mem_ptr(0, mem_p);
|
||||
int buf_payload_len = emac_stack_mem_len(0, mem_p);
|
||||
|
||||
for (; index < buf_payload_len; index++) {
|
||||
if (eth_frame_index < ETH_FRAME_HEADER_LEN) {
|
||||
buf_payload[index] = eth_frame[eth_frame_index];
|
||||
} else if (write_data) {
|
||||
buf_payload[index] = (char) eth_frame_index;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
eth_frame_index++;
|
||||
}
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EMAC_MEMBUF_H
|
||||
#define EMAC_MEMBUF_H
|
||||
|
||||
int emac_if_memory_buffer_read(emac_stack_mem_chain_t *mem_chain_p, unsigned char *eth_frame);
|
||||
void emac_if_memory_buffer_write(emac_stack_mem_chain_t *mem_chain_p, unsigned char *eth_frame, bool write_data);
|
||||
|
||||
#endif /* EMAC_MEMBUF_H */
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#if MBED_CONF_APP_TEST_WIFI || MBED_CONF_APP_TEST_ETHERNET
|
||||
|
||||
#include "emac_tests.h"
|
||||
#include "emac_util.h"
|
||||
#include "emac_ctp.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
void test_emac_broadcast_cb(void)
|
||||
{
|
||||
emac_if_validate_outgoing_msg();
|
||||
|
||||
static int counter = 0;
|
||||
|
||||
// Send three broadcast
|
||||
if (counter < 3) {
|
||||
emac_if_ctp_msg_build(100, eth_mac_broadcast_addr, emac_if_get_own_addr(), emac_if_get_own_addr());
|
||||
counter++;
|
||||
} else if (counter < 6) {
|
||||
counter++;
|
||||
} else if (counter < 9) {
|
||||
emac_if_ctp_msg_build(50, eth_mac_broadcast_addr, emac_if_get_own_addr(), emac_if_get_own_addr());
|
||||
counter++;
|
||||
} else if (counter < 12) {
|
||||
counter++;
|
||||
} else if (counter == 12) {
|
||||
emac_if_reset_outgoing_msg();
|
||||
// ignore errors since just probing
|
||||
RESET_ERROR_FLAGS;
|
||||
#if MBED_CONF_APP_ECHO_SERVER
|
||||
printf("echo server started successfully\r\n\r\n");
|
||||
counter = 255;
|
||||
#else
|
||||
worker_loop_end();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void test_emac_broadcast(void)
|
||||
{
|
||||
RESET_ERROR_FLAGS;
|
||||
SET_TRACE_LEVEL(TRACE_ETH_FRAMES | TRACE_SUCCESS | TRACE_FAILURE);
|
||||
|
||||
worker_loop_start(test_emac_broadcast_cb, 10 * SECOND_TO_MS);
|
||||
|
||||
PRINT_ERROR_FLAGS;
|
||||
TEST_ASSERT_FALSE(ERROR_FLAGS);
|
||||
RESET_OUTGOING_MSG_DATA;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#if MBED_CONF_APP_TEST_WIFI || MBED_CONF_APP_TEST_ETHERNET
|
||||
|
||||
#include "inttypes.h"
|
||||
|
||||
#if MBED_CONF_APP_TEST_WIFI
|
||||
#ifdef TARGET_UBLOX_EVK_ODIN_W2
|
||||
#include "wifi_emac_api.h"
|
||||
#include "OdinWiFiInterface.h"
|
||||
#endif
|
||||
#ifdef TARGET_REALTEK_RTL8195AM
|
||||
#include "rtw_emac.h"
|
||||
#include "RTWInterface.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "emac_api.h"
|
||||
#include "emac_tests.h"
|
||||
#include "emac_util.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
static unsigned char eth_mac_addr[ETH_MAC_ADDR_LEN];
|
||||
|
||||
static char emac_if_link_state_change_cb_data[] = "link_state_change_cb_data";
|
||||
static char emac_if_link_input_cb_data[] = "link_input_cb_data";
|
||||
|
||||
static bool emac_if_init(void);
|
||||
|
||||
void test_emac_initialize()
|
||||
{
|
||||
#if MBED_CONF_APP_TEST_WIFI
|
||||
static WiFiInterface *wifi;
|
||||
|
||||
#ifdef TARGET_UBLOX_EVK_ODIN_W2
|
||||
wifi = new OdinWiFiInterface;
|
||||
#endif
|
||||
#ifdef TARGET_REALTEK_RTL8195AM
|
||||
wifi = new RTWInterface;
|
||||
#endif
|
||||
|
||||
#if MBED_CONF_APP_WIFI_SCAN
|
||||
WiFiAccessPoint ap[30];
|
||||
|
||||
int size = wifi->scan(ap, 30);
|
||||
|
||||
for (int i=0; i<size; i++) {
|
||||
const char *ssid = ap[i].get_ssid();
|
||||
nsapi_security_t security = ap[i].get_security();
|
||||
int8_t rssi = ap[i].get_rssi();
|
||||
char ch = ap[i].get_channel();
|
||||
|
||||
printf("BS %i\r\n", i);
|
||||
printf("ssid %s\r\n", ssid);
|
||||
printf("security %i\r\n", security);
|
||||
printf("rssi %i\r\n", rssi);
|
||||
printf("ch %i\r\n\r\n", ch);
|
||||
}
|
||||
#endif
|
||||
|
||||
wifi->set_credentials(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, MBED_CONF_APP_WIFI_SECURITY);
|
||||
wifi->connect();
|
||||
|
||||
const char *ip_addr = wifi->get_ip_address();
|
||||
printf("connected IP %s\r\n\r\n", ip_addr);
|
||||
#endif
|
||||
|
||||
TEST_ASSERT(emac_if_init());
|
||||
}
|
||||
|
||||
unsigned char *emac_if_get_hw_addr(void)
|
||||
{
|
||||
return ð_mac_addr[0];
|
||||
}
|
||||
|
||||
emac_interface_t *emac_if_get(void)
|
||||
{
|
||||
#if MBED_CONF_APP_TEST_WIFI
|
||||
#ifdef TARGET_UBLOX_EVK_ODIN_W2
|
||||
return wifi_emac_get_interface();
|
||||
#endif
|
||||
#ifdef TARGET_REALTEK_RTL8195AM
|
||||
return wlan_emac_init_interface();
|
||||
#endif
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool emac_if_init(void)
|
||||
{
|
||||
emac_interface_t *emac_if = emac_if_get();
|
||||
|
||||
emac_if->ops.set_link_input_cb(emac_if, emac_if_link_input_cb, emac_if_link_input_cb_data);
|
||||
emac_if->ops.set_link_state_cb(emac_if, emac_if_link_state_change_cb, emac_if_link_state_change_cb_data);
|
||||
|
||||
int hwaddr_len = emac_if->ops.get_hwaddr_size(emac_if);
|
||||
printf("emac hwaddr length %i\r\n\r\n", hwaddr_len);
|
||||
|
||||
if (hwaddr_len == 6) {
|
||||
emac_if->ops.get_hwaddr(emac_if, eth_mac_addr);
|
||||
printf("emac hwaddr %x:%x:%x:%x:%x:%x\r\n\r\n", eth_mac_addr[0],eth_mac_addr[1],eth_mac_addr[2],eth_mac_addr[3],eth_mac_addr[4],eth_mac_addr[5]);
|
||||
}
|
||||
|
||||
int mtu = emac_if->ops.get_mtu_size(emac_if);
|
||||
printf("emac mtu %i\r\n\r\n", mtu);
|
||||
|
||||
char hw_name[11];
|
||||
emac_if->ops.get_ifname(emac_if, hw_name, 10);
|
||||
printf("emac if name %s\r\n\r\n", hw_name);
|
||||
|
||||
if (!emac_if->ops.power_up(emac_if)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#if MBED_CONF_APP_TEST_WIFI || MBED_CONF_APP_TEST_ETHERNET
|
||||
|
||||
#include "emac_tests.h"
|
||||
#include "emac_util.h"
|
||||
#include "emac_ctp.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
void test_emac_unicast_cb(void)
|
||||
{
|
||||
emac_if_validate_outgoing_msg();
|
||||
|
||||
static uint8_t counter = 0;
|
||||
|
||||
// Send three unicast
|
||||
if (counter < 3) {
|
||||
emac_if_ctp_msg_build(100, emac_if_get_echo_server_addr(0), emac_if_get_own_addr(), emac_if_get_own_addr());
|
||||
}
|
||||
|
||||
// End test
|
||||
if (counter > 10) {
|
||||
worker_loop_end();
|
||||
|
||||
if (emac_if_count_outgoing_msg() != 0) {
|
||||
SET_ERROR_FLAGS(TEST_FAILED);
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
void test_emac_unicast()
|
||||
{
|
||||
RESET_ERROR_FLAGS;
|
||||
SET_TRACE_LEVEL(TRACE_ETH_FRAMES | TRACE_SUCCESS | TRACE_FAILURE);
|
||||
|
||||
if (emac_if_count_echo_server_addr()) {
|
||||
worker_loop_start(test_emac_unicast_cb, 1 * SECOND_TO_MS);
|
||||
}
|
||||
|
||||
PRINT_ERROR_FLAGS;
|
||||
TEST_ASSERT_FALSE(ERROR_FLAGS);
|
||||
RESET_OUTGOING_MSG_DATA;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#if MBED_CONF_APP_TEST_WIFI || MBED_CONF_APP_TEST_ETHERNET
|
||||
|
||||
#include "emac_tests.h"
|
||||
#include "emac_util.h"
|
||||
#include "emac_ctp.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
void test_emac_unicast_frame_len_cb(void)
|
||||
{
|
||||
emac_if_validate_outgoing_msg();
|
||||
|
||||
static uint32_t counter = 0;
|
||||
|
||||
// Send unicast to echo server
|
||||
if (counter < 16) {
|
||||
static uint32_t msg_len = 0;
|
||||
|
||||
emac_if_ctp_msg_build(msg_len, emac_if_get_echo_server_addr(0), emac_if_get_own_addr(), emac_if_get_own_addr());
|
||||
|
||||
msg_len += 100;
|
||||
|
||||
if (msg_len > 1514) {
|
||||
msg_len = 1514;
|
||||
}
|
||||
}
|
||||
|
||||
if (counter > 18) {
|
||||
if (emac_if_count_outgoing_msg() == 0) {
|
||||
worker_loop_end();
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
void test_emac_unicast_frame_len()
|
||||
{
|
||||
RESET_ERROR_FLAGS;
|
||||
SET_TRACE_LEVEL(TRACE_SUCCESS | TRACE_FAILURE);
|
||||
|
||||
if (emac_if_count_echo_server_addr()) {
|
||||
worker_loop_start(test_emac_unicast_frame_len_cb, 1 * SECOND_TO_MS);
|
||||
}
|
||||
|
||||
PRINT_ERROR_FLAGS;
|
||||
TEST_ASSERT_FALSE(ERROR_FLAGS);
|
||||
RESET_OUTGOING_MSG_DATA;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EMAC_TESTS_H
|
||||
#define EMAC_TESTS_H
|
||||
|
||||
void test_emac_initialize();
|
||||
void test_emac_broadcast();
|
||||
void test_emac_unicast();
|
||||
void test_emac_unicast_frame_len();
|
||||
|
||||
#endif /* EMAC_TESTS_H */
|
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#if MBED_CONF_APP_TEST_WIFI || MBED_CONF_APP_TEST_ETHERNET
|
||||
|
||||
extern "C" { // netif input
|
||||
#include "tcpip.h"
|
||||
}
|
||||
|
||||
#include "emac_api.h"
|
||||
#include "emac_stack_mem.h"
|
||||
|
||||
#include "emac_tests.h"
|
||||
#include "emac_initialize.h"
|
||||
#include "emac_util.h"
|
||||
#include "emac_membuf.h"
|
||||
#include "emac_ctp.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
typedef struct {
|
||||
int length;
|
||||
int receipt_number;
|
||||
unsigned short flags;
|
||||
unsigned short lifetime;
|
||||
} outgoing_msg_t;
|
||||
|
||||
#define ECHO_SERVER_COUNT 5
|
||||
|
||||
#define OUTGOING_MSG_COUNT 100
|
||||
|
||||
// Event flags
|
||||
#define LINK_UP 0x01
|
||||
#define LINK_DOWN 0x02
|
||||
|
||||
// Hook to lwip input function
|
||||
extern struct netif *netif_list;
|
||||
|
||||
// Broadcast address
|
||||
const unsigned char eth_mac_broadcast_addr[ETH_MAC_ADDR_LEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
|
||||
// Event queue
|
||||
static EventQueue worker_loop_event_queue;
|
||||
static void worker_loop_event_cb(int event);
|
||||
static Event<void(int)> worker_loop_event(&worker_loop_event_queue, worker_loop_event_cb);
|
||||
static void link_input_event_cb(emac_stack_mem_chain_t *mem_chain_p);
|
||||
static Event<void(emac_stack_mem_chain_t *)> link_input_event(&worker_loop_event_queue, link_input_event_cb);
|
||||
|
||||
// Found echo server addresses
|
||||
static unsigned char eth_mac_echo_server_addr[ECHO_SERVER_COUNT][ETH_MAC_ADDR_LEN];
|
||||
static int etc_mac_echo_server_free_index = 0;
|
||||
|
||||
// Outgoing messages
|
||||
static outgoing_msg_t outgoing_msgs[OUTGOING_MSG_COUNT];
|
||||
|
||||
static unsigned int trace_level = 0;
|
||||
static unsigned int error_flags = 0;
|
||||
static unsigned int no_response_cnt = 0;
|
||||
|
||||
int emac_if_find_outgoing_msg(int receipt_number)
|
||||
{
|
||||
for (int i = 0; i < OUTGOING_MSG_COUNT; i++) {
|
||||
if (outgoing_msgs[i].length && outgoing_msgs[i].receipt_number == receipt_number) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void emac_if_free_outgoing_msg(int index)
|
||||
{
|
||||
outgoing_msgs[index].length = 0;
|
||||
}
|
||||
|
||||
int emac_if_count_outgoing_msg(void)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < OUTGOING_MSG_COUNT; i++) {
|
||||
if (outgoing_msgs[i].length) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void emac_if_reset_outgoing_msg(void)
|
||||
{
|
||||
for (int i = 0; i < OUTGOING_MSG_COUNT; i++) {
|
||||
if (outgoing_msgs[i].length) {
|
||||
outgoing_msgs[i].length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int emac_if_add_outgoing_msg(int length)
|
||||
{
|
||||
for (int i = 0; i < OUTGOING_MSG_COUNT; i++) {
|
||||
if (!outgoing_msgs[i].length) {
|
||||
outgoing_msgs[i].receipt_number = 0;
|
||||
outgoing_msgs[i].length = length;
|
||||
outgoing_msgs[i].flags = 0;
|
||||
outgoing_msgs[i].lifetime = 10;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void emac_if_set_outgoing_msg_receipt_num(int index, int receipt_number)
|
||||
{
|
||||
outgoing_msgs[index].receipt_number = receipt_number;
|
||||
}
|
||||
|
||||
void emac_if_set_outgoing_msg_flags(int index, int flags)
|
||||
{
|
||||
outgoing_msgs[index].flags |= flags;
|
||||
}
|
||||
|
||||
void emac_if_timeout_outgoing_msg(void)
|
||||
{
|
||||
for (int i = 0; i < OUTGOING_MSG_COUNT; i++) {
|
||||
if (outgoing_msgs[i].length) {
|
||||
if (outgoing_msgs[i].lifetime) {
|
||||
outgoing_msgs[i].lifetime--;
|
||||
if (outgoing_msgs[i].lifetime == 0) {
|
||||
SET_ERROR_FLAGS(NO_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emac_if_validate_outgoing_msg(void)
|
||||
{
|
||||
static char broadcast_resp_count = 0;
|
||||
|
||||
for (int i = 0; i < OUTGOING_MSG_COUNT; i++) {
|
||||
if (outgoing_msgs[i].length) {
|
||||
|
||||
if (outgoing_msgs[i].flags & RESPONSE_RECEIVED) {
|
||||
|
||||
int failure = outgoing_msgs[i].flags & (INVALID_LENGHT | INVALID_DATA);
|
||||
|
||||
if (failure) {
|
||||
SET_ERROR_FLAGS(MSG_VALID_ERROR);
|
||||
}
|
||||
|
||||
if (!(outgoing_msgs[i].flags & PRINTED)) {
|
||||
if ((trace_level & TRACE_SUCCESS) || ((trace_level & TRACE_FAILURE) && failure)) {
|
||||
printf("response: receipt number %i %s %s %s\r\n\r\n", outgoing_msgs[i].receipt_number,
|
||||
outgoing_msgs[i].flags & INVALID_LENGHT ? "LENGTH INVALID" : "LENGTH OK",
|
||||
outgoing_msgs[i].flags & INVALID_DATA ? "DATA INVALID" : "DATA OK",
|
||||
outgoing_msgs[i].flags & BROADCAST ? "BROADCAST" : "UNICAST");
|
||||
outgoing_msgs[i].flags |= PRINTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (outgoing_msgs[i].flags & BROADCAST) {
|
||||
outgoing_msgs[i].lifetime = 2;
|
||||
broadcast_resp_count++;
|
||||
if (broadcast_resp_count > 5) {
|
||||
emac_if_free_outgoing_msg(i);
|
||||
}
|
||||
} else {
|
||||
emac_if_free_outgoing_msg(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!outgoing_msgs[i].lifetime) {
|
||||
if (!(outgoing_msgs[i].flags & RESPONSE_RECEIVED) && (trace_level & TRACE_FAILURE)) {
|
||||
printf("NO RESPONSE: receipt number %i\r\n\r\n", outgoing_msgs[i].receipt_number);
|
||||
}
|
||||
emac_if_free_outgoing_msg(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emac_if_update_reply_to_outgoing_msg(int receipt_number, int lenght, int invalid_data_index)
|
||||
{
|
||||
int32_t outgoing_msg_index = emac_if_find_outgoing_msg(receipt_number);
|
||||
|
||||
if (outgoing_msg_index >= 0) {
|
||||
outgoing_msgs[outgoing_msg_index].flags |= RESPONSE_RECEIVED;
|
||||
|
||||
#if MBED_CONF_APP_TEST_ETHERNET
|
||||
if (outgoing_msgs[outgoing_msg_index].length < ETH_FRAME_MIN_LEN) {
|
||||
if (lenght != ETH_FRAME_MIN_LEN) {
|
||||
outgoing_msgs[outgoing_msg_index].flags |= INVALID_LENGHT;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
if (outgoing_msgs[outgoing_msg_index].length != lenght) {
|
||||
outgoing_msgs[outgoing_msg_index].flags |= INVALID_LENGHT;
|
||||
}
|
||||
#if MBED_CONF_APP_TEST_ETHERNET
|
||||
}
|
||||
#endif
|
||||
if (invalid_data_index && invalid_data_index < outgoing_msgs[outgoing_msg_index].length) {
|
||||
outgoing_msgs[outgoing_msg_index].flags |= INVALID_DATA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emac_if_add_echo_server_addr(unsigned char *addr)
|
||||
{
|
||||
if (etc_mac_echo_server_free_index == ECHO_SERVER_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < etc_mac_echo_server_free_index; i++) {
|
||||
if (memcmp(ð_mac_echo_server_addr[i][0], addr, ETH_MAC_ADDR_LEN) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(ð_mac_echo_server_addr[etc_mac_echo_server_free_index][0], addr, ETH_MAC_ADDR_LEN);
|
||||
etc_mac_echo_server_free_index++;
|
||||
}
|
||||
|
||||
int emac_if_count_echo_server_addr(void)
|
||||
{
|
||||
return etc_mac_echo_server_free_index;
|
||||
}
|
||||
|
||||
unsigned char *emac_if_get_echo_server_addr(int index)
|
||||
{
|
||||
if (index < etc_mac_echo_server_free_index) {
|
||||
return ð_mac_echo_server_addr[index][0];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void emac_if_set_error_flags(unsigned int error_flags_value)
|
||||
{
|
||||
error_flags |= error_flags_value;
|
||||
|
||||
if (error_flags_value & NO_RESPONSE) {
|
||||
no_response_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int emac_if_get_error_flags(void)
|
||||
{
|
||||
int error_flags_value = error_flags;
|
||||
|
||||
// Indicate no response error only if more than three messages are lost
|
||||
if (error_flags_value & NO_RESPONSE) {
|
||||
if (no_response_cnt < 3) {
|
||||
error_flags_value &= ~NO_RESPONSE;
|
||||
}
|
||||
}
|
||||
|
||||
return error_flags_value;
|
||||
}
|
||||
|
||||
void emac_if_reset_error_flags(void)
|
||||
{
|
||||
error_flags = 0;
|
||||
no_response_cnt = 0;
|
||||
}
|
||||
|
||||
void emac_if_print_error_flags(void)
|
||||
{
|
||||
int error_flags_value = emac_if_get_error_flags();
|
||||
|
||||
char no_resp_message[50];
|
||||
if (error_flags_value & NO_RESPONSE) {
|
||||
snprintf(no_resp_message, 50, "no response from echo server, counter: %i", no_response_cnt);
|
||||
} else if (no_response_cnt > 0) {
|
||||
printf("no response from echo server, counter: %i\r\n\r\n", no_response_cnt);
|
||||
}
|
||||
|
||||
printf("test result: %s%s%s%s%s%s\r\n\r\n",
|
||||
error_flags_value ? "Test FAILED, reason: ": "PASS",
|
||||
error_flags_value & TEST_FAILED ? "test failed ": "",
|
||||
error_flags_value & MSG_VALID_ERROR ? "message content validation error ": "",
|
||||
error_flags_value & OUT_OF_MSG_DATA ? "out of message validation data storage ": "",
|
||||
error_flags_value & NO_FREE_MEM_BUF ? "no free memory buffers ": "",
|
||||
error_flags_value & NO_RESPONSE ? no_resp_message: "");
|
||||
}
|
||||
|
||||
void emac_if_set_trace_level(char trace_level_value)
|
||||
{
|
||||
trace_level = trace_level_value;
|
||||
}
|
||||
|
||||
void emac_if_trace_to_ascii_hex_dump(const char *prefix, int len, unsigned char *data)
|
||||
{
|
||||
int line_len = 0;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if ((line_len % 14) == 0) {
|
||||
if (line_len != 0) {
|
||||
printf("\r\n");
|
||||
}
|
||||
printf("%s %06x", prefix, line_len);
|
||||
}
|
||||
line_len++;
|
||||
printf(" %02x", data[i]);
|
||||
}
|
||||
printf("\r\n\r\n");
|
||||
}
|
||||
|
||||
void emac_if_link_state_change_cb(void *data, bool up)
|
||||
{
|
||||
if (up) {
|
||||
worker_loop_event.post(LINK_UP);
|
||||
} else {
|
||||
worker_loop_event.post(LINK_DOWN);
|
||||
}
|
||||
}
|
||||
|
||||
void emac_if_link_input_cb(void *data, emac_stack_mem_chain_t *mem_chain_p)
|
||||
{
|
||||
link_input_event.post(mem_chain_p);
|
||||
}
|
||||
|
||||
static void link_input_event_cb(emac_stack_mem_chain_t *mem_chain_p)
|
||||
{
|
||||
int lenght = emac_stack_mem_len(0, mem_chain_p);
|
||||
|
||||
if (lenght >= ETH_FRAME_HEADER_LEN) {
|
||||
// Ethernet input frame
|
||||
unsigned char eth_input_frame_data[ETH_FRAME_HEADER_LEN];
|
||||
memset(eth_input_frame_data, 0, ETH_FRAME_HEADER_LEN);
|
||||
|
||||
int invalid_data_index = emac_if_memory_buffer_read(mem_chain_p, eth_input_frame_data);
|
||||
|
||||
if (eth_input_frame_data[12] == 0x90 && eth_input_frame_data[13] == 0x00) {
|
||||
unsigned char eth_output_frame_data[ETH_FRAME_HEADER_LEN];
|
||||
int receipt_number;
|
||||
|
||||
ctp_function function = emac_if_ctp_header_handle(eth_input_frame_data, eth_output_frame_data, emac_if_get_hw_addr(), &receipt_number);
|
||||
|
||||
if (function == CTP_REPLY) {
|
||||
emac_if_update_reply_to_outgoing_msg(receipt_number, lenght, invalid_data_index);
|
||||
#if MBED_CONF_APP_ECHO_SERVER
|
||||
// Echoes only if configured as echo server
|
||||
} else if (function == CTP_FORWARD) {
|
||||
emac_if_memory_buffer_write(mem_chain_p, eth_output_frame_data, false);
|
||||
emac_if_get()->ops.link_out(emac_if_get(), mem_chain_p);
|
||||
#endif
|
||||
}
|
||||
|
||||
emac_if_add_echo_server_addr(ð_input_frame_data[6]);
|
||||
|
||||
emac_stack_mem_free(0, mem_chain_p);
|
||||
|
||||
if (trace_level & TRACE_ETH_FRAMES) {
|
||||
printf("LEN %i\r\n\r\n", lenght);
|
||||
const char trace_type[] = "INP>";
|
||||
emac_if_trace_to_ascii_hex_dump(trace_type, ETH_FRAME_HEADER_LEN, eth_input_frame_data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Forward other than CTP frames to lwip
|
||||
struct netif *netif;
|
||||
|
||||
/* loop through netif's */
|
||||
netif = netif_list;
|
||||
if (netif != NULL) {
|
||||
struct pbuf *p = (struct pbuf *)mem_chain_p;
|
||||
|
||||
/* pass all packets to ethernet_input, which decides what packets it supports */
|
||||
if (netif->input(p, netif) != ERR_OK) {
|
||||
emac_stack_mem_free(0, mem_chain_p);
|
||||
}
|
||||
} else {
|
||||
emac_stack_mem_free(0, mem_chain_p);
|
||||
}
|
||||
}
|
||||
|
||||
void worker_loop_start(void (*test_step_cb_fnc)(void), int timeout)
|
||||
{
|
||||
int test_step_cb_timer = worker_loop_event_queue.call_every(timeout, test_step_cb_fnc);
|
||||
int timeout_outgoing_msg_timer = worker_loop_event_queue.call_every(1000, emac_if_timeout_outgoing_msg);
|
||||
|
||||
#if MBED_CONF_APP_ECHO_SERVER
|
||||
worker_loop_event_queue.dispatch_forever();
|
||||
#else
|
||||
worker_loop_event_queue.dispatch(600 * SECOND_TO_MS);
|
||||
#endif
|
||||
|
||||
worker_loop_event_queue.cancel(test_step_cb_timer);
|
||||
worker_loop_event_queue.cancel(timeout_outgoing_msg_timer);
|
||||
|
||||
worker_loop_event_queue.dispatch(5);
|
||||
}
|
||||
|
||||
static void worker_loop_event_cb(int event)
|
||||
{
|
||||
if (event == LINK_UP) {
|
||||
printf("cable connected\r\n\r\n");
|
||||
}
|
||||
|
||||
if (event == LINK_DOWN) {
|
||||
printf("cable disconnected\r\n\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void worker_loop_end(void)
|
||||
{
|
||||
worker_loop_event_queue.break_dispatch();
|
||||
}
|
||||
|
||||
unsigned char *emac_if_get_own_addr(void)
|
||||
{
|
||||
return (emac_if_get_hw_addr());
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EMAC_UTIL_H
|
||||
#define EMAC_UTIL_H
|
||||
|
||||
#define SECOND_TO_US 1000000
|
||||
#define SECOND_TO_MS 1000
|
||||
#define MS_TO_US 1000
|
||||
|
||||
extern const unsigned char eth_mac_broadcast_addr[];
|
||||
|
||||
// Trace flags
|
||||
#define TRACE_ETH_FRAMES 0x01
|
||||
#define TRACE_SUCCESS 0x02
|
||||
#define TRACE_FAILURE 0x04
|
||||
#define SET_TRACE_LEVEL(level) emac_if_set_trace_level(level)
|
||||
|
||||
// Message validation flags
|
||||
#define BROADCAST 0x01
|
||||
#define RESPONSE_RECEIVED 0x02
|
||||
#define INVALID_LENGHT 0x04
|
||||
#define INVALID_DATA 0x08
|
||||
#define PRINTED 0x10
|
||||
|
||||
#define RESET_OUTGOING_MSG_DATA emac_if_reset_outgoing_msg()
|
||||
|
||||
// General error flags
|
||||
#define TEST_FAILED 0x01
|
||||
#define MSG_VALID_ERROR 0x02
|
||||
#define OUT_OF_MSG_DATA 0x04
|
||||
#define NO_FREE_MEM_BUF 0x08
|
||||
#define NO_RESPONSE 0x10
|
||||
|
||||
#define ERROR_FLAGS emac_if_get_error_flags()
|
||||
#define RESET_ERROR_FLAGS emac_if_reset_error_flags()
|
||||
#define PRINT_ERROR_FLAGS emac_if_print_error_flags()
|
||||
#define SET_ERROR_FLAGS(flags) emac_if_set_error_flags(flags)
|
||||
|
||||
#define ETH_FRAME_HEADER_LEN 28
|
||||
#define ETH_FRAME_MIN_LEN 60
|
||||
#define ETH_MAC_ADDR_LEN 6
|
||||
|
||||
int emac_if_find_outgoing_msg(int receipt_number);
|
||||
void emac_if_free_outgoing_msg(int index);
|
||||
int emac_if_count_outgoing_msg(void);
|
||||
void emac_if_reset_outgoing_msg(void);
|
||||
int emac_if_add_outgoing_msg(int length);
|
||||
void emac_if_timeout_outgoing_msg(void);
|
||||
void emac_if_validate_outgoing_msg(void);
|
||||
void emac_if_set_outgoing_msg_receipt_num(int index, int receipt_number);
|
||||
void emac_if_set_outgoing_msg_flags(int index, int flags);
|
||||
|
||||
void emac_if_add_echo_server_addr(unsigned char *addr);
|
||||
int emac_if_count_echo_server_addr(void);
|
||||
unsigned char *emac_if_get_echo_server_addr(int index);
|
||||
|
||||
void emac_if_set_error_flags(unsigned int error_flags_value);
|
||||
unsigned int emac_if_get_error_flags(void);
|
||||
void emac_if_reset_error_flags(void);
|
||||
void emac_if_print_error_flags(void);
|
||||
|
||||
void emac_if_set_trace_level(char trace_level_value);
|
||||
|
||||
void emac_if_trace_to_ascii_hex_dump(const char *prefix, int len, char *data);
|
||||
|
||||
void emac_if_link_state_change_cb(void *data, bool up);
|
||||
|
||||
unsigned char *emac_if_get_own_addr(void);
|
||||
|
||||
extern void emac_if_link_input_cb(void *data, void *mem_chain_p);
|
||||
extern void emac_if_link_state_change_cb(void *data, bool up);
|
||||
|
||||
void worker_loop_start(void (*test_step_cb_fnc)(void), int timeout);
|
||||
void worker_loop_end(void);
|
||||
|
||||
void emac_if_init_main_thread(void);
|
||||
|
||||
#endif /* EMAC_UTIL_H */
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if !defined(MBED_CONF_APP_TEST_WIFI) || \
|
||||
!defined(MBED_CONF_APP_TEST_ETHERNET) || \
|
||||
!defined(MBED_CONF_APP_ECHO_SERVER) || \
|
||||
!defined(MBED_CONF_APP_WIFI_SCAN) || \
|
||||
!defined(MBED_CONF_APP_WIFI_SSID ) || \
|
||||
!defined(MBED_CONF_APP_WIFI_SECURITY) || \
|
||||
!defined(MBED_CONF_APP_WIFI_PASSWORD)
|
||||
#error [NOT_SUPPORTED] Requires parameters from mbed_app.json
|
||||
#endif
|
||||
|
||||
#if !MBED_CONF_APP_TEST_WIFI && !MBED_CONF_APP_TEST_ETHERNET
|
||||
#error [NOT_SUPPORTED] Either wifi or ethernet testing need to be enabled
|
||||
#endif
|
||||
#if MBED_CONF_APP_TEST_WIFI
|
||||
#if !defined(TARGET_UBLOX_EVK_ODIN_W2) && !defined(TARGET_REALTEK_RTL8195AM)
|
||||
#error [NOT_SUPPORTED] Tests are valid only for UBLOX_EVK_ODIN_W2 and REALTEK_RTL8195AM
|
||||
#endif
|
||||
#endif
|
||||
#if MBED_CONF_APP_TEST_ETHERNET
|
||||
#error [NOT_SUPPORTED] Ethernet testing not supported
|
||||
#endif
|
||||
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#include "emac_tests.h"
|
||||
#include "emac_util.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
// Test setup
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases) {
|
||||
#if !MBED_CONF_APP_ECHO_SERVER
|
||||
GREENTEA_SETUP(600, "default_auto");
|
||||
#endif
|
||||
return verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("EMAC interface initialize", test_emac_initialize),
|
||||
Case("EMAC interface broadcast", test_emac_broadcast),
|
||||
Case("EMAC interface unicast", test_emac_unicast),
|
||||
Case("EMAC interface unicast frame length", test_emac_unicast_frame_len),
|
||||
Case("EMAC interface broadcast (run again)", test_emac_broadcast)
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
|
||||
int main()
|
||||
{
|
||||
return !Harness::run(specification);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"config": {
|
||||
"test-ethernet": {
|
||||
"help": "Enable ethernet testing",
|
||||
"value": 0
|
||||
},
|
||||
"test-wifi": {
|
||||
"help": "Enable wifi testing",
|
||||
"value": 1
|
||||
},
|
||||
"echo-server": {
|
||||
"help": "Build test to be echo server",
|
||||
"value": 0
|
||||
},
|
||||
"wifi-scan": {
|
||||
"help": "Scan and list access points",
|
||||
"value": 0
|
||||
},
|
||||
"wifi-ssid": {
|
||||
"help": "WiFi SSID for network",
|
||||
"value": "\"SSID\""
|
||||
},
|
||||
"wifi-security": {
|
||||
"help": "WiFi Security",
|
||||
"value": "NSAPI_SECURITY_WPA_WPA2"
|
||||
},
|
||||
"wifi-password": {
|
||||
"help": "WiFi Password",
|
||||
"value": "\"PASSWORD\""
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue