BA / Mbed OS BaBoRo1
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers emac_ctp.cpp Source File

emac_ctp.cpp

00001 /*
00002  * Copyright (c) 2017, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "greentea-client/test_env.h"
00019 #include "unity/unity.h"
00020 #include "utest.h"
00021 
00022 #if MBED_CONF_APP_TEST_WIFI || MBED_CONF_APP_TEST_ETHERNET
00023 
00024 #include "mbed.h"
00025 
00026 #include "lwip/opt.h" /* ETH_PAD_SIZE */
00027 
00028 #include "emac_stack_mem.h"
00029 #include "emac_api.h"
00030 
00031 #include "emac_tests.h"
00032 #include "emac_ctp.h"
00033 
00034 #include "emac_initialize.h"
00035 #include "emac_util.h"
00036 #include "emac_membuf.h"
00037 
00038 using namespace utest::v1;
00039 
00040 // Unique identifier for message
00041 static int receipt_number = 0;
00042 
00043 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)
00044 {
00045     memcpy(&eth_frame[0], dest_addr, 6);
00046     memcpy(&eth_frame[6], origin_addr, 6);
00047 
00048     eth_frame[12] = 0x90; /* loop back */
00049     eth_frame[13] = 0x00;
00050 
00051     eth_frame[14] = 0x00; /* skip count */
00052     eth_frame[15] = 0x00;
00053 
00054     eth_frame[16] = 0x02; /* function, forward */
00055     eth_frame[17] = 0x00;
00056 
00057     memcpy(&eth_frame[18], forward_addr, 6);
00058 
00059     eth_frame[24] = 0x01; /* function, reply */
00060     eth_frame[25] = 0x00;
00061 
00062     receipt_number++;
00063 
00064     eth_frame[26] = receipt_number; /* receipt number */
00065     eth_frame[27] = receipt_number >> 8;
00066 
00067     return receipt_number;
00068 }
00069 
00070 ctp_function emac_if_ctp_header_handle(unsigned char *eth_input_frame, unsigned char *eth_output_frame, unsigned char *origin_addr, int *receipt_number)
00071 {
00072     if (eth_input_frame[12] != 0x90 || eth_input_frame[13] != 0x00) {
00073         return CTP_NONE;
00074     }
00075 
00076     int skip_count = eth_input_frame[15] << 8 | eth_input_frame[14];
00077     unsigned char *ethernet_ptr = &eth_input_frame[16] + skip_count;
00078 
00079     int function = ethernet_ptr[1] << 8 | ethernet_ptr[0];
00080     ethernet_ptr += 2;
00081 
00082     // Forward
00083     if (function == 0x0002) {
00084         memcpy(eth_output_frame, eth_input_frame, ETH_FRAME_HEADER_LEN);
00085         // Update skip count
00086         skip_count += 8;
00087         eth_output_frame[14] = skip_count;
00088         eth_output_frame[15] = skip_count >> 8;
00089         // Set forward address to destination address
00090         memcpy(&eth_output_frame[0], ethernet_ptr, 6);
00091         // Copy own address to origin
00092         memcpy(&eth_output_frame[6], origin_addr, 6);
00093         return CTP_FORWARD;
00094     // reply
00095     } else if (function == 0x0001) {
00096         *receipt_number = ethernet_ptr[1] << 8 | ethernet_ptr[0];
00097         return CTP_REPLY;
00098     }
00099 
00100     return CTP_NONE;
00101 }
00102 
00103 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)
00104 {
00105     if (eth_frame_len < ETH_FRAME_HEADER_LEN) {
00106         eth_frame_len = ETH_FRAME_HEADER_LEN;
00107     }
00108 
00109     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]);
00110 
00111     int outgoing_msg_index = emac_if_add_outgoing_msg(eth_frame_len);
00112 
00113     if (outgoing_msg_index < 0) {
00114         SET_ERROR_FLAGS(OUT_OF_MSG_DATA);
00115         return;
00116     }
00117 
00118     emac_stack_mem_chain_t *mem_chain_p = emac_stack_mem_alloc(0, eth_frame_len + ETH_PAD_SIZE, 0);
00119 
00120     if (!mem_chain_p) {
00121         SET_ERROR_FLAGS(NO_FREE_MEM_BUF);
00122         emac_if_free_outgoing_msg(outgoing_msg_index);
00123         return;
00124     }
00125 
00126     if (memcmp(dest_addr, eth_mac_broadcast_addr, 6) == 0) {
00127         emac_if_set_outgoing_msg_flags(outgoing_msg_index, BROADCAST);
00128     }
00129 
00130     unsigned char eth_output_frame_data[ETH_FRAME_HEADER_LEN];
00131     int receipt_number = emac_if_ctp_header_build(eth_output_frame_data, dest_addr, origin_addr, forward_addr);
00132     emac_if_set_outgoing_msg_receipt_num(outgoing_msg_index, receipt_number);
00133 
00134     emac_if_memory_buffer_write(mem_chain_p, eth_output_frame_data, true);
00135 
00136     //emac_if->ops.link_out(hw_driver, mem_chain_p);
00137     emac_if_get()->ops.link_out(emac_if_get(), mem_chain_p);
00138 
00139     emac_stack_mem_free(0, mem_chain_p);
00140 }
00141 
00142 #endif
00143