├── Cfg └── Template │ └── iperf_cfg.h ├── LICENSE ├── NOTICE ├── OS ├── uCOS-II │ └── iperf_os.c └── uCOS-III │ └── iperf_os.c ├── Reporter └── Terminal │ ├── iperf_rep.c │ ├── iperf_rep.h │ ├── iperf_shell.c │ └── iperf_shell.h ├── Source ├── iperf-c.c ├── iperf-s.c ├── iperf.c └── iperf.h └── readme.md /Cfg/Template/iperf_cfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/IPerf 4 | * TCP-IP Transfer Measurement Utility 5 | * 6 | * Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * IPERF CONFIGURATION FILE 21 | * 22 | * TEMPLATE 23 | * 24 | * Filename : iperf_cfg.h 25 | * Version : V2.04.00 26 | ********************************************************************************************************* 27 | */ 28 | 29 | /* 30 | ********************************************************************************************************* 31 | * TASKS PRIORITIES 32 | * Notes: (1) Task priorities configuration values should be used by the IPerf OS port. The following task priorities 33 | * should be defined: 34 | * 35 | * IPERF_OS_CFG_TASK_PRIO 36 | * 37 | * Task priorities can be defined either in this configuration file 'iperf_cfg.h' or in a global 38 | * OS tasks priorities configuration header file which must be included in 'iperf_cfg.h'. 39 | ********************************************************************************************************* 40 | */ 41 | 42 | #define IPERF_OS_CFG_TASK_PRIO 12u /* IPerf task priority. */ 43 | 44 | 45 | /* 46 | ********************************************************************************************************* 47 | * STACK SIZES 48 | * Size of the task stack (# of OS_STK entries) 49 | ********************************************************************************************************* 50 | */ 51 | 52 | #define IPERF_OS_CFG_TASK_STK_SIZE 1024u /* IPerf task stack size. */ 53 | 54 | 55 | /* 56 | ********************************************************************************************************* 57 | * IPERF 58 | * 59 | * Note(s) : (1) Configures the maximum number of tests that can be started and/or running at a 60 | * given time. 61 | * 62 | * (2) Configure the size of the ring array holding the tests results. The maximum number of test 63 | * SHOULD be equal or greater than the Iperf queue size. 64 | ********************************************************************************************************* 65 | */ 66 | 67 | #define IPERF_CFG_Q_SIZE 2u /* Configure IPerf queue size (see Note #1). */ 68 | 69 | #define IPERF_CFG_MAX_NBR_TEST 5u /* Configure the maximum number of tests (See Note #2). */ 70 | 71 | /* Configure IPerf bandwidth calculation : */ 72 | #define IPERF_CFG_BANDWIDTH_CALC_EN DEF_DISABLED 73 | /* DEF_ENABLED Bandwidth calculation ENABLED */ 74 | /* DEF_DISABLED Bandwidth calculation DISABLED */ 75 | 76 | /* Configure IPerf CPU usage calculation : */ 77 | #define IPERF_CFG_CPU_USAGE_MAX_CALC_EN DEF_ENABLED 78 | /* DEF_ENABLED CPU usage calculation ENABLED */ 79 | /* DEF_DISABLED CPU usage calculation DISABLED */ 80 | 81 | #define IPERF_CFG_BUF_LEN 8192u /* Configure maximum buffer size used to send/receive. */ 82 | 83 | 84 | 85 | /* Configure IPerf server : */ 86 | #define IPERF_CFG_SERVER_EN DEF_ENABLED 87 | /* DEF_ENABLED UDP & TCP server ENABLED */ 88 | /* DEF_DISABLED UDP & TCP server DISABLED */ 89 | 90 | #define IPERF_CFG_SERVER_ACCEPT_MAX_RETRY 10u /* Configure server maximum of retries on accept. */ 91 | 92 | #define IPERF_CFG_SERVER_ACCEPT_MAX_DLY_MS 500u /* Configure server delay between retries on accept. */ 93 | 94 | #define IPERF_CFG_SERVER_ACCEPT_MAX_TIMEOUT_MS 5000u /* Configure server maximum inactivity time on accept. */ 95 | 96 | #define IPERF_CFG_SERVER_TCP_RX_MAX_TIMEOUT_MS 5000u /* Configure server maximum inactivity time on TCP Rx. */ 97 | 98 | #define IPERF_CFG_SERVER_UDP_RX_MAX_TIMEOUT_MS 5000u /* Configure server maximum inactivity time on UDP Rx. */ 99 | 100 | 101 | 102 | /* Configure IPerf client : */ 103 | #define IPERF_CFG_CLIENT_EN DEF_ENABLED 104 | /* DEF_ENABLED UDP & TCP client ENABLED */ 105 | /* DEF_DISABLED UDP & TCP client DISABLED */ 106 | 107 | /* Configure client to bind on same port as server */ 108 | #define IPERF_CFG_CLIENT_BIND_EN DEF_DISABLED 109 | /* DEF_ENABLED bind client ENABLED */ 110 | /* DEF_DISABLED bind client DISABLED */ 111 | 112 | #define IPERF_CFG_CLIENT_CONN_MAX_RETRY 10u /* Configure client maximum of retries on connect. */ 113 | 114 | #define IPERF_CFG_CLIENT_CONN_MAX_DLY_MS 500u /* Configure client delay between retries on connect. */ 115 | 116 | #define IPERF_CFG_CLIENT_CONN_MAX_TIMEOUT_MS 5000u /* Configure client maximum inactivity time on connect. */ 117 | 118 | #define IPERF_CFG_CLIENT_TCP_TX_MAX_TIMEOUT_MS 5000u /* Configure client maximum inactivity time on TCP Tx. */ 119 | 120 | 121 | /* 122 | ********************************************************************************************************* 123 | * TRACE / DEBUG CONFIGURATION 124 | ********************************************************************************************************* 125 | */ 126 | 127 | #ifndef TRACE_LEVEL_OFF 128 | #define TRACE_LEVEL_OFF 0 129 | #endif 130 | 131 | #ifndef TRACE_LEVEL_INFO 132 | #define TRACE_LEVEL_INFO 1 133 | #endif 134 | 135 | #ifndef TRACE_LEVEL_DBG 136 | #define TRACE_LEVEL_DBG 2 137 | #endif 138 | 139 | #define IPERF_TRACE_LEVEL TRACE_LEVEL_OFF 140 | #define IPERF_TRACE printf 141 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | ATTENTION ALL USERS OF THIS REPOSITORY: 2 | 3 | The original work found in this repository is provided by Silicon Labs under the 4 | Apache License, Version 2.0. 5 | 6 | Any third party may contribute derivative works to the original work in which 7 | modifications are clearly identified as being licensed under: 8 | 9 | (1) the Apache License, Version 2.0 or a compatible open source license; or 10 | (2) under a proprietary license with a copy of such license deposited. 11 | 12 | All posted derivative works must clearly identify which license choice has been 13 | elected. 14 | 15 | No such posted derivative works will be considered to be a “Contribution” under 16 | the Apache License, Version 2.0. 17 | 18 | SILICON LABS MAKES NO WARRANTY WITH RESPECT TO ALL POSTED THIRD PARTY CONTENT 19 | AND DISCLAIMS ALL OTHER WARRANTIES OR LIABILITIES, INCLUDING ALL WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, OWNERSHIP, 21 | NON-INFRINGEMENT, AND NON-MISAPPROPRIATION. 22 | 23 | In the event a derivative work is desired to be submitted to Silicon Labs as a 24 | “Contribution” under the Apache License, Version 2.0, a “Contributor” must give 25 | written email notice to micrium@weston-embedded.com. Unless an email response in 26 | the affirmative to accept the derivative work as a “Contribution”, such email 27 | submission should be considered to have not been incorporated into the original 28 | work. 29 | -------------------------------------------------------------------------------- /OS/uCOS-II/iperf_os.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/IPerf 4 | * TCP-IP Transfer Measurement Utility 5 | * 6 | * Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * IPERF OPERATING SYSTEM LAYER 21 | * 22 | * Micrium uC/OS-II 23 | * 24 | * Filename : iperf_os.c 25 | * Version : V2.04.00 26 | ********************************************************************************************************* 27 | * Note(s) : (1) Assumes uC/OS-II V2.86 (or more recent version) is included in the project build. 28 | * 29 | * (2) REQUIREs the following uC/OS-II features to be ENABLED : 30 | * 31 | * ------- FEATURE -------- --------- MINIMUM CONFIGURATION FOR IPERF/OS PORT ---------- 32 | * 33 | * (a) Message Queue 34 | * (1) OS_Q_EN Enabled 35 | * 36 | * (b) Task Statistic If IPERF_CFG_CPU_USAGE_MAX_CALC_EN is enabled 37 | * (1) OS_TASK_STAT_EN Enabled 38 | ********************************************************************************************************* 39 | */ 40 | 41 | /* 42 | ********************************************************************************************************* 43 | ********************************************************************************************************* 44 | * INCLUDE FILES 45 | ********************************************************************************************************* 46 | ********************************************************************************************************* 47 | */ 48 | 49 | #include 50 | 51 | #include /* See this 'iperf_os.h Note #1'. */ 52 | 53 | 54 | /* 55 | ********************************************************************************************************* 56 | ********************************************************************************************************* 57 | * LOCAL DEFINES 58 | ********************************************************************************************************* 59 | ********************************************************************************************************* 60 | */ 61 | 62 | 63 | /* 64 | ********************************************************************************************************* 65 | * OS TASK/OBJECT NAME DEFINES 66 | ********************************************************************************************************* 67 | */ 68 | 69 | /* -------------------- TASK NAMES -------------------- */ 70 | #define IPERF_OS_TASK_NAME "IPerf Task" 71 | 72 | #define IPERF_OS_TASK_NAME_SIZE_MAX 11 /* Max of IPerf task name size. */ 73 | 74 | 75 | /* -------------------- OBJ NAMES --------------------- */ 76 | #define IPERF_OS_Q_NAME "IPerf Cmd Q" 77 | 78 | #define IPERF_OS_Q_NAME_SIZE_MAX 12 /* Max of Iperf Q name sizes. */ 79 | 80 | 81 | /* 82 | ********************************************************************************************************* 83 | ********************************************************************************************************* 84 | * LOCAL GLOBAL VARIABLES 85 | ********************************************************************************************************* 86 | ********************************************************************************************************* 87 | */ 88 | 89 | /* --------------------- TASK STK --------------------- */ 90 | static OS_STK IPERF_OS_TaskStk[IPERF_OS_CFG_TASK_STK_SIZE]; 91 | 92 | /* ---------------------- CMD Q ----------------------- */ 93 | static OS_EVENT *IPERF_OS_Q_Ptr; 94 | static void *IPERF_OS_Q[IPERF_CFG_Q_SIZE]; 95 | 96 | 97 | /* 98 | ********************************************************************************************************* 99 | ********************************************************************************************************* 100 | * LOCAL FUNCTION PROTOTYPES 101 | ********************************************************************************************************* 102 | ********************************************************************************************************* 103 | */ 104 | 105 | /* ------------- IPERF MAIN TASK FUNCTION ------------- */ 106 | static void IPerf_OS_Task (void *p_data); 107 | 108 | 109 | /* 110 | ********************************************************************************************************* 111 | ********************************************************************************************************* 112 | * LOCAL CONFIGURATION ERRORS 113 | ********************************************************************************************************* 114 | ********************************************************************************************************* 115 | */ 116 | 117 | /* See 'iperf_os.c Note #1'. */ 118 | #if (OS_VERSION < 286) 119 | #error "OS_VERSION [SHOULD be >= V2.86]" 120 | #endif 121 | 122 | 123 | 124 | /* See 'iperf_os.c Note #2a'. */ 125 | #if (OS_Q_EN < 1u) 126 | #error "OS_Q_EN illegally #define'd in 'os_cfg.h' [MUST be > 0, (see 'iperf_os.c Note #2a1')]" 127 | #endif 128 | 129 | 130 | 131 | /* See 'iperf_os.c Note #2b'. */ 132 | #if ((IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) && \ 133 | (OS_TASK_STAT_EN < 1)) 134 | #error "OS_TASK_STAT_EN illegally #define'd in 'os_cfg.h' [MUST be > 0, (see 'iperf_os.c Note #2b1')]" 135 | #endif 136 | 137 | 138 | 139 | 140 | #ifndef IPERF_OS_CFG_TASK_PRIO 141 | #error "IPERF_OS_CFG_TASK_PRIO not #define'd in 'app_cfg.h' [MUST be >= 0u]" 142 | #elif (IPERF_OS_CFG_TASK_PRIO < 0u) 143 | #error "IPERF_OS_CFG_TASK_PRIO illegally #define'd in 'app_cfg.h' [MUST be >= 0u]" 144 | #endif 145 | 146 | 147 | 148 | 149 | #ifndef IPERF_CFG_Q_SIZE 150 | #error "IPERF_CFG_Q_SIZE not #define'd in 'app_cfg.h' [MUST be > 0u]" 151 | #elif (IPERF_CFG_Q_SIZE < 1u) 152 | #error "IPERF_CFG_Q_SIZE illegally #define'd in 'app_cfg.h' [MUST be > 0u]" 153 | #endif 154 | 155 | 156 | 157 | 158 | #ifndef IPERF_OS_CFG_TASK_STK_SIZE 159 | #error "IPERF_OS_CFG_TASK_STK_SIZE not #define'd in 'app_cfg.h' [MUST be > 0u]" 160 | #elif (IPERF_OS_CFG_TASK_STK_SIZE < 1u) 161 | #error "IPERF_OS_CFG_TASK_STK_SIZE illegally #define'd in 'app_cfg.h' [MUST be > 0u]" 162 | #endif 163 | 164 | 165 | /* 166 | ********************************************************************************************************* 167 | ********************************************************************************************************* 168 | * IPERF FUNCTIONS 169 | ********************************************************************************************************* 170 | ********************************************************************************************************* 171 | */ 172 | 173 | 174 | /* 175 | ********************************************************************************************************* 176 | * IPerf_OS_Init() 177 | * 178 | * Description : (1) Perform IPerf/OS initialisation: 179 | * 180 | * (a) Create IPerf Cmd Q. 181 | * (b) Set IPerf Cms Q name. 182 | * (c) Create IPerf task. 183 | * (d) Set IPerf task name. 184 | * 185 | * 186 | * Argument(s) : p_err Pointer to variable that will receive the return error code from this function 187 | * 188 | * IPERF_OS_ERR_NONE IPerf/OS initialization successful. 189 | * 190 | * IPERF_OS_ERR_INIT_Q IPerf initialization Q 191 | * NOT successfully initialized. 192 | * 193 | * IPERF_OS_ERR_INIT_TASK IPerf initialization task 194 | * NOT successfully initialized. 195 | * 196 | * Return(s) : none. 197 | * 198 | * Caller(s) : IPerf_Init(). 199 | * 200 | * Note(s) : none. 201 | ********************************************************************************************************* 202 | */ 203 | 204 | void IPerf_OS_Init (IPERF_ERR *p_err) 205 | { 206 | INT8U os_err; 207 | 208 | /* ---------- INITIALIZE/CREATE IPERF QUEUE ----------- */ 209 | IPERF_OS_Q_Ptr = OSQCreate(&IPERF_OS_Q[0], 210 | IPERF_CFG_Q_SIZE + 1); 211 | 212 | if (IPERF_OS_Q_Ptr == (OS_EVENT *)0) { 213 | *p_err = IPERF_OS_ERR_INIT_Q; 214 | return; 215 | } 216 | 217 | #if (((OS_VERSION >= 288) && (OS_EVENT_NAME_EN > 0)) || \ 218 | ((OS_VERSION < 288) && (OS_EVENT_NAME_SIZE >= IPERF_OS_Q_NAME_SIZE_MAX))) 219 | OSEventNameSet((OS_EVENT *) IPERF_OS_Q_Ptr, 220 | (INT8U *) IPERF_OS_Q_NAME, 221 | (INT8U *)&os_err); 222 | if (os_err != OS_ERR_NONE) { 223 | *p_err = IPERF_OS_ERR_INIT_Q; 224 | return; 225 | } 226 | #endif 227 | 228 | 229 | /* Create IPerf task. */ 230 | #if (OS_TASK_CREATE_EXT_EN == 1) 231 | 232 | #if (OS_STK_GROWTH == 1) 233 | os_err = OSTaskCreateExt((void (*)(void *)) IPerf_OS_Task, 234 | (void * ) 0, 235 | (OS_STK * )&IPERF_OS_TaskStk[IPERF_OS_CFG_TASK_STK_SIZE - 1], 236 | (INT8U ) IPERF_OS_CFG_TASK_PRIO, 237 | (INT16U ) IPERF_OS_CFG_TASK_PRIO, 238 | (OS_STK * )&IPERF_OS_TaskStk[0], 239 | (INT32U ) IPERF_OS_CFG_TASK_STK_SIZE, 240 | (void * ) 0, 241 | (INT16U )(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK)); 242 | #else 243 | os_err = OSTaskCreateExt((void (*)(void *)) IPerf_OS_Task, 244 | (void * ) 0, 245 | (OS_STK * )&IPERF_OS_TaskStk[0], 246 | (INT8U ) IPERF_OS_CFG_TASK_PRIO, 247 | (INT16U ) IPERF_OS_CFG_TASK_PRIO, 248 | (OS_STK * )&IPERF_OS_TaskStk[IPERF_OS_CFG_TASK_STK_SIZE - 1], 249 | (INT32U ) IPERF_OS_CFG_TASK_STK_SIZE, 250 | (void * ) 0, 251 | (INT16U )(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK)); 252 | #endif 253 | 254 | #else 255 | 256 | #if (OS_STK_GROWTH == 1) 257 | os_err = OSTaskCreate((void (*)(void *)) IPerf_OS_Task, 258 | (void * ) 0, 259 | (OS_STK * )&IPERF_OS_TaskStk[IPERF_OS_CFG_TASK_STK_SIZE - 1], 260 | (INT8U ) IPERF_OS_CFG_TASK_PRIO); 261 | #else 262 | os_err = OSTaskCreate((void (*)(void *)) IPerf_OS_Task, 263 | (void * ) 0, 264 | (OS_STK * )&IPERF_OS_TaskStk[0], 265 | (INT8U ) IPERF_OS_CFG_TASK_PRIO); 266 | #endif 267 | 268 | #endif 269 | 270 | if (os_err != OS_ERR_NONE) { 271 | *p_err = IPERF_OS_ERR_INIT_TASK; 272 | return; 273 | } 274 | 275 | 276 | #if (((OS_VERSION >= 288) && (OS_TASK_NAME_EN > 0)) || \ 277 | ((OS_VERSION < 288) && (OS_TASK_NAME_SIZE >= IPERF_OS_TASK_NAME_SIZE_MAX))) 278 | OSTaskNameSet((INT8U ) IPERF_OS_CFG_TASK_PRIO, 279 | (INT8U *) IPERF_OS_TASK_NAME, 280 | (INT8U *)&os_err); 281 | if (os_err != OS_ERR_NONE) { 282 | *p_err = IPERF_OS_ERR_INIT_TASK; 283 | return; 284 | } 285 | #endif 286 | 287 | *p_err = IPERF_OS_ERR_NONE; 288 | } 289 | 290 | 291 | /* 292 | ********************************************************************************************************* 293 | * IPerf_OS_Task() 294 | * 295 | * Description : OS-dependent shell task to proceed IPerf test handler. 296 | * 297 | * Argument(s) : p_data Pointer to task initialization data (required by uC/OS-III). 298 | * 299 | * Return(s) : none. 300 | * 301 | * Caller(s) : IPerf_OS_Init(). 302 | * 303 | * Note(s) : none. 304 | ********************************************************************************************************* 305 | */ 306 | 307 | static void IPerf_OS_Task (void *p_data) 308 | { 309 | (void)&p_data; /* Prevent compiler warning. */ 310 | 311 | while (DEF_ON) { 312 | IPerf_TestTaskHandler(); 313 | } 314 | } 315 | 316 | 317 | /* 318 | ********************************************************************************************************* 319 | * IPerf_OS_TestQ_Wait() 320 | * 321 | * Description : Wait on IPerf test ID of test to start. 322 | * 323 | * Argument(s) : p_err Pointer to variable that will receive the return error code from this function : 324 | * 325 | * IPERF_OS_ERR_Q_NONE Message received. 326 | * IPERF_OS_ERR_MSG_Q Message NOT received. 327 | * 328 | * Return(s) : Test ID to start. 329 | * 330 | * Caller(s) : IPerf_TestTaskHandler(). 331 | * 332 | * This function is an INTERNAL IPerf function & MUST NOT be called by application function(s). 333 | * 334 | * Note(s) : (1) IPerf message from parser MUST be acquired --i.e. MUST wait for message; do NOT timeout. 335 | ********************************************************************************************************* 336 | */ 337 | 338 | IPERF_TEST_ID IPerf_OS_TestQ_Wait (IPERF_ERR *p_err) 339 | { 340 | void *p_q; 341 | CPU_ADDR msg_val; 342 | IPERF_TEST_ID test_id; 343 | INT8U os_err; 344 | 345 | 346 | p_q = OSQPend((OS_EVENT *) IPERF_OS_Q_Ptr, /* Wait on IPerf receive test Q. */ 347 | (INT16U ) 0, /* Preferably without timeout (see Note #1). */ 348 | (INT8U *)&os_err); 349 | switch (os_err) { 350 | case OS_ERR_NONE: 351 | msg_val = (CPU_ADDR )p_q; 352 | test_id = (IPERF_TEST_ID)msg_val; /* Decode interface of signaled receive test ID. */ 353 | *p_err = IPERF_OS_ERR_NONE; 354 | break; 355 | 356 | case OS_ERR_TIMEOUT: 357 | case OS_ERR_PEVENT_NULL: 358 | case OS_ERR_EVENT_TYPE: 359 | case OS_ERR_PEND_ISR: 360 | case OS_ERR_PEND_LOCKED: 361 | case OS_ERR_PEND_ABORT: 362 | default: 363 | test_id = IPERF_TEST_ID_NONE; 364 | *p_err = IPERF_OS_ERR_Q; 365 | break; 366 | } 367 | 368 | return (test_id); 369 | } 370 | 371 | 372 | /* 373 | ********************************************************************************************************* 374 | * IPerf_OS_TestQ_Post() 375 | * 376 | * Description : Post IPerf test ID of test to start. 377 | * 378 | * Argument(s) : test_id Test ID of test to start. 379 | * 380 | * p_err Pointer to variable that will receive the return error code from this function 381 | * 382 | * IPERF_OS_ERR_NONE Message successfully posted. 383 | * IPERF_OS_ERR_MSG_Q Message NOT successfully posted. 384 | * 385 | * Return(s) : none. 386 | * 387 | * Caller(s) : IPerf_Parse(). 388 | * 389 | * This function is an INTERNAL IPerf function & MUST NOT be called by application function(s). 390 | * 391 | * Note(s) : none. 392 | ********************************************************************************************************* 393 | */ 394 | 395 | void IPerf_OS_TestQ_Post (IPERF_TEST_ID iperf_test_id, 396 | IPERF_ERR *p_err) 397 | { 398 | INT8U os_err; 399 | CPU_ADDR iperf_test_id_msg; 400 | 401 | 402 | iperf_test_id_msg = (CPU_ADDR)iperf_test_id; 403 | 404 | os_err = OSQPost((OS_EVENT *)IPERF_OS_Q_Ptr, /* Signal IPerf receive test task with test_id. */ 405 | (void *)iperf_test_id_msg); 406 | switch (os_err) { 407 | case OS_ERR_NONE: 408 | *p_err = IPERF_OS_ERR_NONE; 409 | break; 410 | 411 | 412 | case OS_ERR_Q_FULL: 413 | case OS_ERR_PEVENT_NULL: 414 | case OS_ERR_EVENT_TYPE: 415 | default: 416 | *p_err = IPERF_OS_ERR_Q; 417 | break; 418 | } 419 | } 420 | 421 | 422 | /* 423 | ********************************************************************************************************* 424 | * IPerf_OS_CPU_Usage() 425 | * 426 | * Description : Get current CPU usage 427 | * 428 | * Argument(s) : none. 429 | * 430 | * Return(s) : none. 431 | * 432 | * Caller(s) : IPerf_ServerTCP(), 433 | * IPerf_ServerUDP(), 434 | * IPerf_ClientTCP(), 435 | * IPerf_ClientUDP(). 436 | * 437 | * This function is an INTERNAL IPerf function & MUST NOT be called by application function(s). 438 | * 439 | * Note(s) : none. 440 | ********************************************************************************************************* 441 | */ 442 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 443 | CPU_INT16U IPerf_OS_CPU_Usage (void) 444 | { 445 | return (OSCPUUsage); 446 | } 447 | #endif 448 | 449 | -------------------------------------------------------------------------------- /OS/uCOS-III/iperf_os.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/IPerf 4 | * TCP-IP Transfer Measurement Utility 5 | * 6 | * Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * IPERF OPERATING SYSTEM LAYER 21 | * 22 | * Micrium uC/OS-III 23 | * 24 | * Filename : iperf_os.c 25 | * Version : V2.04.00 26 | ********************************************************************************************************* 27 | * Note(s) : (1) Assumes uC/OS-III V3.01.0 (or more recent version) is included in the project build. 28 | * 29 | * (2) REQUIREs the following uC/OS-III feature(s) to be ENABLED : 30 | * 31 | * ------- FEATURE ------ -- MINIMUM CONFIGURATION FOR IPERF/OS PORT -- 32 | 33 | * (a) Messages OS_CFG_MSG_POOL_SIZE >= IPERF_CFG_Q_SIZE (see 'OS OBJECT DEFINES') 34 | * 35 | * (b) Message Queue 36 | * (1) OS_CFG_TASK_Q_EN Enabled 37 | * 38 | * (c) Task Statistic If IPERF_CFG_CPU_USAGE_MAX_CALC_EN is enabled 39 | * (1) OS_CFG_TASK_PROFILE_EN Enabled 40 | ********************************************************************************************************* 41 | */ 42 | 43 | 44 | /* 45 | ********************************************************************************************************* 46 | ********************************************************************************************************* 47 | * INCLUDE FILES 48 | ********************************************************************************************************* 49 | ********************************************************************************************************* 50 | */ 51 | 52 | #define MICRIUM_SOURCE 53 | #include "../../Source/iperf.h" 54 | #include 55 | #include 56 | /* See this 'iperf_os.c Note #1'. */ 57 | 58 | /* 59 | ********************************************************************************************************* 60 | ********************************************************************************************************* 61 | * LOCAL CONFIGURATION ERRORS 62 | ********************************************************************************************************* 63 | ********************************************************************************************************* 64 | */ 65 | 66 | /* See 'iperf_os.c Note #1'. */ 67 | #if (OS_VERSION < 3010u) 68 | #error "OS_VERSION [SHOULD be >= V3.01.0]" 69 | #endif 70 | 71 | 72 | 73 | /* See 'iperf_os.c Note #2b'. */ 74 | #if (OS_CFG_TASK_Q_EN < 1u) 75 | #error "OS_CFG_TASK_Q_EN illegally #define'd in 'os_cfg.h' [MUST be > 0, (see 'iperf_os.c Note #2b')]" 76 | #endif 77 | 78 | 79 | /* See 'iperf_os.c Note #2c'. */ 80 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 81 | 82 | #if (OS_CFG_TASK_PROFILE_EN < 1u) 83 | #error "OS_CFG_TASK_PROFILE_EN illegally #define'd in 'os_cfg.h'. MUST be >= 1u." 84 | #endif 85 | 86 | #if (OS_CFG_DBG_EN < 1) 87 | #error "OS_CFG_DBG_EN illegally #define'd in 'os_cfg.h'. MUST be >= 1u." 88 | #endif 89 | 90 | #if (OS_CFG_STAT_TASK_EN < 1) 91 | #error "OS_CFG_STAT_TASK_EN illegally #define'd in 'os_cfg.h'. MUST be >= 1u." 92 | #endif 93 | #endif 94 | 95 | 96 | 97 | #ifndef IPERF_OS_CFG_TASK_PRIO 98 | #error "IPERF_OS_CFG_TASK_PRIO not #define'd in 'iperf_cfg.h' [MUST be >= 0u]" 99 | #elif (IPERF_OS_CFG_TASK_PRIO < 0u) 100 | #error "IPERF_OS_CFG_TASK_PRIO illegally #define'd in 'iperf_cfg.h' [MUST be >= 0u]" 101 | #endif 102 | 103 | 104 | 105 | #ifndef IPERF_CFG_Q_SIZE 106 | #error "IPERF_CFG_Q_SIZE not #define'd in 'iperf_cfg.h' [MUST be > 0u]" 107 | 108 | #elif (IPERF_CFG_Q_SIZE < 1u) 109 | #error "IPERF_CFG_Q_SIZE illegally #define'd in 'iperf_cfg.h' [MUST be > 0u]" 110 | 111 | #elif (IPERF_CFG_Q_SIZE > IPERF_CFG_MAX_NBR_TEST) 112 | #error "IPERF_CFG_Q_SIZE illegally #define'd in 'iperf_cfg.h' [MUST be <= IPERF_CFG_MAX_NBR_TEST]" 113 | #endif 114 | 115 | 116 | 117 | 118 | #ifndef IPERF_OS_CFG_TASK_STK_SIZE 119 | #error "IPERF_OS_CFG_TASK_STK_SIZE not #define'd in 'iperf_cfg.h' [MUST be > 0u]" 120 | #elif (IPERF_OS_CFG_TASK_STK_SIZE < 1u) 121 | #error "IPERF_OS_CFG_TASK_STK_SIZE illegally #define'd in 'iperf_cfg.h' [MUST be > 0u]" 122 | #endif 123 | 124 | 125 | /* 126 | ********************************************************************************************************* 127 | ********************************************************************************************************* 128 | * LOCAL DEFINES 129 | ********************************************************************************************************* 130 | ********************************************************************************************************* 131 | */ 132 | 133 | 134 | /* 135 | ********************************************************************************************************* 136 | * OS TASK/OBJECT NAME DEFINES 137 | ********************************************************************************************************* 138 | */ 139 | 140 | /* -------------------- TASK NAMES -------------------- */ 141 | #define IPERF_OS_TASK_NAME "IPerf Task" 142 | 143 | 144 | /* 145 | ********************************************************************************************************* 146 | ********************************************************************************************************* 147 | * LOCAL GLOBAL VARIABLES 148 | ********************************************************************************************************* 149 | ********************************************************************************************************* 150 | */ 151 | 152 | 153 | /* --------------------- TASK TCB --------------------- */ 154 | static OS_TCB IPerf_TaskTCB; 155 | 156 | 157 | /* -------------------- TASK STACK -------------------- */ 158 | static CPU_STK IPERF_OS_TaskStk[IPERF_OS_CFG_TASK_STK_SIZE]; 159 | 160 | 161 | /* 162 | ********************************************************************************************************* 163 | ********************************************************************************************************* 164 | * LOCAL FUNCTION PROTOTYPES 165 | ********************************************************************************************************* 166 | ********************************************************************************************************* 167 | */ 168 | 169 | /* ---------- IPERF TASK MANAGEMENT FUNCTION ---------- */ 170 | static void IPerf_OS_Task (void *p_data); 171 | 172 | 173 | /* 174 | ********************************************************************************************************* 175 | ********************************************************************************************************* 176 | * IPERF FUNCTIONS 177 | ********************************************************************************************************* 178 | ********************************************************************************************************* 179 | */ 180 | 181 | 182 | /* 183 | ********************************************************************************************************* 184 | * IPerf_OS_Init() 185 | * 186 | * Description : (1) Perform IPerf/OS initialisation: 187 | * 188 | * (a) Create IPerf Cmd Q. 189 | * (b) Create IPerf task. 190 | * 191 | * 192 | * Argument(s) : p_err Pointer to variable that will receive the return error code from this function 193 | * 194 | * IPERF_OS_ERR_NONE IPerf/OS initialization successful. 195 | * IPERF_OS_ERR_INIT_TASK IPerf initialization task 196 | * NOT successfully initialized. 197 | * 198 | * Return(s) : none. 199 | * 200 | * Caller(s) : IPerf_Init(). 201 | * 202 | * Note(s) : none. 203 | ********************************************************************************************************* 204 | */ 205 | 206 | void IPerf_OS_Init (IPERF_ERR *p_err) 207 | { 208 | OS_ERR os_err; 209 | /* Create IPerf task. */ 210 | OSTaskCreate((OS_TCB *)&IPerf_TaskTCB, 211 | (CPU_CHAR *) IPERF_OS_TASK_NAME, 212 | (OS_TASK_PTR ) IPerf_OS_Task, 213 | (void *) 0u, 214 | (OS_PRIO ) IPERF_OS_CFG_TASK_PRIO, 215 | (CPU_STK *)&IPERF_OS_TaskStk[0], 216 | (CPU_STK_SIZE)(IPERF_OS_CFG_TASK_STK_SIZE / 10u), 217 | (CPU_STK_SIZE) IPERF_OS_CFG_TASK_STK_SIZE, 218 | (OS_MSG_QTY ) IPERF_CFG_Q_SIZE + 1u, 219 | (OS_TICK ) 0u, 220 | (void *) 0u, 221 | (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), 222 | (OS_ERR *)&os_err); 223 | 224 | if (os_err != OS_ERR_NONE) { 225 | *p_err = IPERF_OS_ERR_INIT_TASK; 226 | return; 227 | } 228 | 229 | *p_err = IPERF_OS_ERR_NONE; 230 | } 231 | 232 | 233 | /* 234 | ********************************************************************************************************* 235 | * IPerf_OS_Task() 236 | * 237 | * Description : OS-dependent shell task to proceed IPerf test handler. 238 | * 239 | * Argument(s) : p_data Pointer to task initialization data (required by uC/OS-III). 240 | * 241 | * Return(s) : none. 242 | * 243 | * Caller(s) : IPerf_OS_Init(). 244 | * 245 | * Note(s) : none. 246 | ********************************************************************************************************* 247 | */ 248 | 249 | static void IPerf_OS_Task (void *p_data) 250 | { 251 | (void)&p_data; /* Prevent compiler warning. */ 252 | 253 | while (DEF_ON) { 254 | IPerf_TestTaskHandler(); 255 | } 256 | } 257 | 258 | 259 | /* 260 | ********************************************************************************************************* 261 | * IPerf_OS_TestQ_Wait() 262 | * 263 | * Description : Wait on IPerf test ID of test to start. 264 | * 265 | * Argument(s) : p_err Pointer to variable that will receive the return error code from this function : 266 | * 267 | * IPERF_OS_ERR_Q_NONE Message received. 268 | * IPERF_OS_ERR_Q Message NOT received. 269 | * 270 | * Return(s) : Test ID to start. 271 | * 272 | * Caller(s) : IPerf_TestTaskHandler(). 273 | * 274 | * This function is an INTERNAL IPerf function & MUST NOT be called by application function(s). 275 | * 276 | * Note(s) : (1) IPerf message from parser MUST be acquired --i.e. MUST wait for message; do NOT timeout. 277 | ********************************************************************************************************* 278 | */ 279 | 280 | IPERF_TEST_ID IPerf_OS_TestQ_Wait (IPERF_ERR *p_err) 281 | { 282 | IPERF_TEST_ID iperf_test_id; 283 | OS_ERR os_err; 284 | OS_MSG_SIZE os_msg_size; 285 | void *p_msg; 286 | CPU_ADDR msg_val; 287 | 288 | /* Wait on IPerf task queue ... */ 289 | p_msg = OSTaskQPend((OS_TICK ) 0u, /* ... without timeout (see Note #1b). */ 290 | (OS_OPT ) OS_OPT_PEND_BLOCKING, 291 | (OS_MSG_SIZE *)&os_msg_size, 292 | (CPU_TS *) 0u, 293 | (OS_ERR *)&os_err); 294 | 295 | switch (os_err) { 296 | case OS_ERR_NONE: 297 | msg_val = (CPU_ADDR)p_msg; 298 | iperf_test_id = (IPERF_TEST_ID)msg_val; /* Decode interface of signaled receive test ID. */ 299 | *p_err = IPERF_OS_ERR_NONE; 300 | break; 301 | 302 | 303 | case OS_ERR_Q_EMPTY: 304 | case OS_ERR_TIMEOUT: 305 | case OS_ERR_PEND_ISR: 306 | case OS_ERR_PEND_ABORT: 307 | case OS_ERR_PEND_WOULD_BLOCK: 308 | case OS_ERR_SCHED_LOCKED: 309 | default: 310 | iperf_test_id = IPERF_TEST_ID_NONE; 311 | *p_err = IPERF_OS_ERR_Q; 312 | break; 313 | } 314 | 315 | return (iperf_test_id); 316 | } 317 | 318 | 319 | /* 320 | ********************************************************************************************************* 321 | * IPerf_OS_TestQ_Post() 322 | * 323 | * Description : Post IPerf test ID of test to start. 324 | * 325 | * Argument(s) : test_id Test ID of test to start. 326 | * 327 | * p_err Pointer to variable that will receive the return error code from this function 328 | * 329 | * IPERF_OS_ERR_NONE Message successfully posted. 330 | * IPERF_OS_ERR_Q Message NOT successfully posted. 331 | * 332 | * Return(s) : none. 333 | * 334 | * Caller(s) : IPerf_Parse(). 335 | * 336 | * This function is an INTERNAL IPerf function & MUST NOT be called by application function(s). 337 | * 338 | * Note(s) : none. 339 | ********************************************************************************************************* 340 | */ 341 | 342 | void IPerf_OS_TestQ_Post (IPERF_TEST_ID iperf_test_id, 343 | IPERF_ERR *p_err) 344 | { 345 | OS_ERR os_err; 346 | CPU_ADDR iperf_test_id_msg; 347 | 348 | 349 | iperf_test_id_msg = (CPU_ADDR)iperf_test_id; 350 | 351 | OSTaskQPost((OS_TCB *)&IPerf_TaskTCB, /* Post msg to msg queue. */ 352 | (void *) iperf_test_id_msg, 353 | (OS_MSG_SIZE) 0u, 354 | (OS_OPT ) OS_OPT_POST_FIFO, 355 | (OS_ERR *)&os_err); 356 | 357 | switch (os_err) { 358 | case OS_ERR_NONE: 359 | *p_err = IPERF_OS_ERR_NONE; 360 | break; 361 | 362 | 363 | case OS_ERR_Q_MAX: 364 | case OS_ERR_MSG_POOL_EMPTY: 365 | case OS_ERR_STATE_INVALID: 366 | default: 367 | *p_err = IPERF_OS_ERR_Q; 368 | break; 369 | } 370 | } 371 | 372 | 373 | /* 374 | ********************************************************************************************************* 375 | * IPerf_OS_CPU_Usage() 376 | * 377 | * Description : Get current CPU usage 378 | * 379 | * Argument(s) : none. 380 | * 381 | * Return(s) : none. 382 | * 383 | * Caller(s) : IPerf_ServerTCP(), 384 | * IPerf_ServerUDP(), 385 | * IPerf_ClientTCP(), 386 | * IPerf_ClientUDP(). 387 | * 388 | * This function is an INTERNAL IPerf function & MUST NOT be called by application function(s). 389 | * 390 | * Note(s) : none. 391 | ********************************************************************************************************* 392 | */ 393 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 394 | CPU_INT16U IPerf_OS_CPU_Usage (void) 395 | { 396 | CPU_INT16U usage; 397 | 398 | 399 | usage = 10000u - OSIdleTaskTCB.CPUUsage; 400 | 401 | return (usage); 402 | } 403 | #endif 404 | 405 | -------------------------------------------------------------------------------- /Reporter/Terminal/iperf_rep.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/IPerf 4 | * TCP-IP Transfer Measurement Utility 5 | * 6 | * Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * IPERF REPORTER 21 | * 22 | * Filename : iperf_rep.h 23 | * Version : V2.04.00 24 | ********************************************************************************************************* 25 | */ 26 | 27 | 28 | /* 29 | ********************************************************************************************************* 30 | ********************************************************************************************************* 31 | * MODULE 32 | * Note(s) : (1) This header file is protected from multiple pre-processor inclusion through use of the 33 | * IPerf reporter present pre-processor macro definition. 34 | ********************************************************************************************************* 35 | ********************************************************************************************************* 36 | */ 37 | 38 | #ifndef IPERF_REPORTER_MODULE_PRESENT 39 | #define IPERF_REPORTER_MODULE_PRESENT 40 | 41 | 42 | /* 43 | ********************************************************************************************************* 44 | ********************************************************************************************************* 45 | * INCLUDE FILES 46 | * 47 | * Note(s) : (1) The IPerf module files are located in the following directories : 48 | * 49 | * (a) \\iperf_cfg.h 50 | * 51 | * (b) \\Source\net_*.* 52 | * 53 | * (c) (1) \\Source\iperf.h 54 | * \iperf.c 55 | * \iperf-c.c 56 | * \iperf-s.c 57 | * 58 | * (2) \\OS\\iperf_os.* 59 | * 60 | * (3) \\Reporter\\iperf_rep.* 61 | * 62 | * where 63 | * directory path for Your Product's Application 64 | * directory path for network protocol suite 65 | * directory path for IPerf module 66 | * directory name for specific operating system (OS) 67 | * directory name for specific output device/stream 68 | * 69 | * (2) CPU-configuration software files are located in the following directories : 70 | * 71 | * (a) \\cpu_*.* 72 | * (b) \\\\cpu*.* 73 | * 74 | * where 75 | * directory path for common CPU-compiler software 76 | * directory name for specific processor (CPU) 77 | * directory name for specific compiler 78 | * 79 | * (3) NO compiler-supplied standard library functions SHOULD be used but MAY be implemented in 80 | * the custom library module(s) : 81 | * 82 | * (a) \\lib_*.* 83 | * 84 | * where 85 | * directory path for custom library software 86 | * 87 | * (4) Compiler MUST be configured to include as additional include path directories : 88 | * 89 | * (a) '\\' directory See Note #1a 90 | * 91 | * (b) '\\' directory See Note #1b 92 | * 93 | * (c) '\\' directories See Note #1c 94 | * 95 | * (d) (1) '\\' directory See Note #2a 96 | * (2) '\\\\' directory See Note #2b 97 | * 98 | * (e) '\\' directory See Note #3a 99 | ********************************************************************************************************* 100 | ********************************************************************************************************* 101 | */ 102 | 103 | #include "../../Source/iperf.h" 104 | 105 | 106 | /* 107 | ********************************************************************************************************* 108 | ********************************************************************************************************* 109 | * EXTERNS 110 | ********************************************************************************************************* 111 | ********************************************************************************************************* 112 | */ 113 | 114 | #ifdef IPERF_REPORTER_MODULE 115 | #define IPERF_REPORTER_EXT 116 | #else 117 | #define IPERF_REPORTER_EXT extern 118 | #endif 119 | 120 | 121 | /* 122 | ********************************************************************************************************* 123 | ********************************************************************************************************* 124 | * DEFINES 125 | ********************************************************************************************************* 126 | ********************************************************************************************************* 127 | */ 128 | 129 | #define IPERF_REPORTER_STR_BUF_MAX_LEN 256u 130 | #define IPERF_REPORTER_MIN_DLY_MS 100u 131 | 132 | 133 | /* 134 | ********************************************************************************************************* 135 | ********************************************************************************************************* 136 | * FUNCTION PROTOTYPES 137 | ********************************************************************************************************* 138 | ********************************************************************************************************* 139 | */ 140 | 141 | void IPerf_Reporter(IPERF_TEST_ID test_id, /* Start IPerf reporter for specified test ID. */ 142 | IPERF_OUT_FNCT p_out_fnct, 143 | IPERF_OUT_PARAM *p_out_opt); 144 | 145 | 146 | /* 147 | ********************************************************************************************************* 148 | ********************************************************************************************************* 149 | * MODULE END 150 | ********************************************************************************************************* 151 | ********************************************************************************************************* 152 | */ 153 | 154 | #endif /* End of IPerf reporter module include (see Note #1). */ 155 | 156 | -------------------------------------------------------------------------------- /Reporter/Terminal/iperf_shell.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/IPerf 4 | * TCP-IP Transfer Measurement Utility 5 | * 6 | * Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * IPERF REPORTER 21 | * 22 | * Filename : iperf_shell.c 23 | * Version : V2.04.00 24 | ********************************************************************************************************* 25 | */ 26 | 27 | 28 | /* 29 | ********************************************************************************************************* 30 | ********************************************************************************************************* 31 | * INCLUDE FILES 32 | ********************************************************************************************************* 33 | ********************************************************************************************************* 34 | */ 35 | 36 | #define MICRIUM_SOURCE 37 | #include "iperf_shell.h" 38 | #include "iperf_rep.h" 39 | 40 | 41 | /* 42 | ********************************************************************************************************* 43 | ********************************************************************************************************* 44 | * LOCAL DEFINES 45 | ********************************************************************************************************* 46 | ********************************************************************************************************* 47 | */ 48 | 49 | #define IPERF_CMD_NAME "iperf" 50 | #define IPERF_CMD_TBL_NAME IPERF_CMD_NAME 51 | #define IPERF_CMD_NAME_START IPERF_CMD_NAME 52 | 53 | 54 | /* 55 | ********************************************************************************************************* 56 | ********************************************************************************************************* 57 | * LOCAL DATA TYPES 58 | ********************************************************************************************************* 59 | ********************************************************************************************************* 60 | */ 61 | 62 | typedef struct { 63 | SHELL_OUT_FNCT OutFnct; 64 | SHELL_CMD_PARAM *OutOpt_Ptr; 65 | } IPERF_SHELL_OUT_PARAM; 66 | 67 | 68 | /* 69 | ********************************************************************************************************* 70 | ********************************************************************************************************* 71 | * LOCAL TABLES 72 | ********************************************************************************************************* 73 | ********************************************************************************************************* 74 | */ 75 | 76 | 77 | static SHELL_CMD IPerfCmdTbl[] = 78 | { 79 | {IPERF_CMD_NAME_START, IPerfShell_Start}, 80 | {0, 0 } 81 | }; 82 | 83 | 84 | /* 85 | ********************************************************************************************************* 86 | ********************************************************************************************************* 87 | * LOCAL FUNCTION PROTOTYPES 88 | ********************************************************************************************************* 89 | ********************************************************************************************************* 90 | */ 91 | 92 | void IPerfShell_OutputFnct (CPU_CHAR *p_buf, 93 | IPERF_OUT_PARAM *p_param); 94 | 95 | 96 | /* 97 | ********************************************************************************************************* 98 | * IPerfShell_Init() 99 | * 100 | * Description : Add IPerf functions to uC-Shell. 101 | * 102 | * Argument(s) : p_err is a pointer to an error code which will be returned to your application: 103 | * 104 | * IPERF_ERR_NONE No error. 105 | * 106 | * IPERF_ERR_EXT_SHELL_INIT Command table not added to uC-Shell 107 | * 108 | * Return(s) : none. 109 | * 110 | * Caller(s) : AppTaskStart(). 111 | * 112 | * Note(s) : none. 113 | ********************************************************************************************************* 114 | */ 115 | 116 | void IPerfShell_Init (IPERF_ERR *p_err) 117 | { 118 | SHELL_ERR shell_err; 119 | 120 | 121 | Shell_CmdTblAdd(IPERF_CMD_TBL_NAME, IPerfCmdTbl, &shell_err); 122 | 123 | if (shell_err == SHELL_ERR_NONE) { 124 | *p_err = IPERF_ERR_NONE; 125 | } else { 126 | *p_err = IPERF_ERR_EXT_SHELL_INIT; 127 | return; 128 | } 129 | } 130 | 131 | 132 | 133 | 134 | /* 135 | ********************************************************************************************************* 136 | * IPerfShell_Start() 137 | * 138 | * Description : IPERF_TEST_TODO Add function description. 139 | * 140 | * Argument(s) : argc IPERF_TEST_TODO Add description for 'argc' 141 | * 142 | * p_argv IPERF_TEST_TODO Add description for 'p_argv' 143 | * 144 | * out_fnct IPERF_TEST_TODO Add description for 'out_fnct' 145 | * 146 | * p_cmd_param IPERF_TEST_TODO Add description for 'p_cmd_param' 147 | * 148 | * Return(s) : IPERF_TEST_TODO Add return value description. 149 | * 150 | * Caller(s) : IPerfCmdTbl. 151 | * 152 | * Note(s) : none. 153 | ********************************************************************************************************* 154 | */ 155 | 156 | CPU_INT16S IPerfShell_Start (CPU_INT16U argc, 157 | CPU_CHAR *p_argv[], 158 | SHELL_OUT_FNCT out_fnct, 159 | SHELL_CMD_PARAM *p_cmd_param) 160 | { 161 | IPERF_SHELL_OUT_PARAM outparam; 162 | IPERF_OUT_PARAM param; 163 | IPERF_TEST_ID test_id; 164 | IPERF_ERR err_iperf; 165 | 166 | 167 | outparam.OutFnct = out_fnct; 168 | outparam.OutOpt_Ptr = p_cmd_param; 169 | param.p_out_opt = &outparam; 170 | 171 | test_id = IPerf_TestShellStart(argc, p_argv, &IPerfShell_OutputFnct, ¶m, &err_iperf); 172 | if (err_iperf == IPERF_ERR_NONE) { 173 | IPerf_Reporter(test_id, 174 | &IPerfShell_OutputFnct, 175 | ¶m); 176 | } 177 | 178 | return (1); 179 | } 180 | 181 | 182 | /* 183 | ********************************************************************************************************* 184 | * IPerfShell_OutputFnct() 185 | * 186 | * Description : Output a string. 187 | * 188 | * Argument(s) : p_buf Pointer to buffer to output. 189 | * 190 | * Return(s) : none. 191 | * 192 | * Caller(s) : IPerfShell_Start(). 193 | * 194 | * Note(s) : (1) The string pointed to by p_buf has to be NUL ('\0') terminated. 195 | ********************************************************************************************************* 196 | */ 197 | 198 | void IPerfShell_OutputFnct (CPU_CHAR *p_buf, 199 | IPERF_OUT_PARAM *p_param) 200 | { 201 | IPERF_SHELL_OUT_PARAM *p_param_shell; 202 | SHELL_CMD_PARAM *p_cmd_param; 203 | CPU_INT16S output; 204 | CPU_INT32U str_len; 205 | 206 | /* ----------------- VALIDATE POINTER ----------------- */ 207 | if (p_buf == (CPU_CHAR *)0) { 208 | return; 209 | } 210 | /* ------------------ DISPLAY STRING ------------------ */ 211 | p_param_shell = p_param->p_out_opt; 212 | p_cmd_param = p_param_shell->OutOpt_Ptr; 213 | 214 | 215 | str_len = Str_Len(p_buf); 216 | output = p_param_shell->OutFnct(p_buf, 217 | str_len, 218 | p_cmd_param->pout_opt); 219 | (void)&output; 220 | } 221 | 222 | -------------------------------------------------------------------------------- /Reporter/Terminal/iperf_shell.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/IPerf 4 | * TCP-IP Transfer Measurement Utility 5 | * 6 | * Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * IPERF SHELL 21 | * 22 | * Filename : iperf_shell.h 23 | * Version : V2.04.00 24 | ********************************************************************************************************* 25 | */ 26 | 27 | 28 | /* 29 | ********************************************************************************************************* 30 | ********************************************************************************************************* 31 | * MODULE 32 | * Note(s) : (1) This header file is protected from multiple pre-processor inclusion through use of the 33 | * IPerf reporter present pre-processor macro definition. 34 | ********************************************************************************************************* 35 | ********************************************************************************************************* 36 | */ 37 | 38 | #ifndef IPERF_SHELL_MODULE_PRESENT 39 | #define IPERF_SHELL_MODULE_PRESENT 40 | 41 | 42 | /* 43 | ********************************************************************************************************* 44 | ********************************************************************************************************* 45 | * INCLUDE FILES 46 | * 47 | * Note(s) : (1) The IPerf module files are located in the following directories : 48 | * 49 | * (a) \\iperf_cfg.h 50 | * 51 | * (b) \\Source\net_*.* 52 | * 53 | * (c) \\Source\iperf.h 56 | * \iperf.c 57 | * \iperf-c.c 58 | * \iperf-s.c 59 | * 60 | * (2) \\OS\\iperf_os.* 61 | * 62 | * (3) \\Reporter\\iperf_rep.* 63 | * 64 | * where 65 | * directory path for Your Product's Application 66 | * directory path for network protocol suite 67 | * directory path for IPerf module 68 | * directory name for specific operating system (OS) 69 | * directory name for specific output device/stream 70 | * 71 | * (2) CPU-configuration software files are located in the following directories : 72 | * 73 | * (a) \\cpu_*.* 74 | * (b) \\\\cpu*.* 75 | * 76 | * where 77 | * directory path for common CPU-compiler software 78 | * directory name for specific processor (CPU) 79 | * directory name for specific compiler 80 | * 81 | * (3) NO compiler-supplied standard library functions SHOULD be used but MAY be implemented in 82 | * the custom library module(s) : 83 | * 84 | * (a) \\lib_*.* 85 | * 86 | * where 87 | * directory path for custom library software 88 | * 89 | * (4) Compiler MUST be configured to include as additional include path directories : 90 | * 91 | * (a) '\\' directory See Note #1a 92 | * 93 | * (b) '\\' directory See Note #1b 94 | * 95 | * (c) '\\' directories See Note #1c 96 | * 97 | * (d) (1) '\\' directory See Note #2a 98 | * (2) '\\\\' directory See Note #2b 99 | * 100 | * (e) '\\' directory See Note #3a 101 | ********************************************************************************************************* 102 | ********************************************************************************************************* 103 | */ 104 | 105 | #include "../../Source/iperf.h" 106 | #include 107 | 108 | 109 | /* 110 | ********************************************************************************************************* 111 | ********************************************************************************************************* 112 | * EXTERNS 113 | ********************************************************************************************************* 114 | ********************************************************************************************************* 115 | */ 116 | 117 | #ifdef IPERF_SHELL_MODULE 118 | #define IPERF_SHELL_EXT 119 | #else 120 | #define IPERF_SHELL_EXT extern 121 | #endif 122 | 123 | 124 | /* 125 | ********************************************************************************************************* 126 | ********************************************************************************************************* 127 | * FUNCTION PROTOTYPES 128 | ********************************************************************************************************* 129 | ********************************************************************************************************* 130 | */ 131 | 132 | void IPerfShell_Init (IPERF_ERR *p_err); 133 | 134 | CPU_INT16S IPerfShell_Start(CPU_INT16U argc, 135 | CPU_CHAR *p_argv[], 136 | SHELL_OUT_FNCT out_fnct, 137 | SHELL_CMD_PARAM *p_cmd_param); 138 | 139 | 140 | /* 141 | ********************************************************************************************************* 142 | ********************************************************************************************************* 143 | * MODULE END 144 | ********************************************************************************************************* 145 | ********************************************************************************************************* 146 | */ 147 | 148 | #endif /* End of IPerf shell module include (see Note #1). */ 149 | 150 | -------------------------------------------------------------------------------- /Source/iperf-c.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/IPerf 4 | * TCP-IP Transfer Measurement Utility 5 | * 6 | * Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * IPERF CLIENT 21 | * 22 | * Filename : iperf-c.c 23 | * Version : V2.04.00 24 | ********************************************************************************************************* 25 | * Note(s) : (1) Assumes uC/TCP-IP V2.05 (or more recent version) is included in the project build. 26 | * 27 | * (2) (a) (1) uC/IPerf is designed to work with NLANR IPerf 2.0.2 or higher. 28 | * 29 | * (2) uC/IPerf should be compatible with kPerf or jPerf using IPerf 2.0.2 or higher. 30 | * 31 | * (b) Supports NLANR Iperf with the following restrictions/constraints : 32 | * 33 | * (1) TCP: 34 | * (A) Multi-threaded NOT supported on both mode 35 | * (B) Measure bandwith Supported on both mode 36 | * (C) Report MSS/MTU size & observed read sizes NOT supported on both mode 37 | * (D) Support for TCP window size via socket buffer Supported on server mode 38 | * 39 | * (2) UDP: 40 | * (A) Multi-threaded NOT supported on both mode 41 | * (B) Create UDP streams of specified bandwidth NOT supported on client mode 42 | * (C) Measure packet loss Supported on server mode 43 | * (D) Measure delay jitter NOT supported on both mode 44 | * (E) Multicast capable NOT supported on both mode 45 | * 46 | * (c) More information about NLANR IPerf can be obtained online at 47 | * http://www.onl.wustl.edu/restricted/iperf.html. 48 | ********************************************************************************************************* 49 | */ 50 | 51 | 52 | /* 53 | ********************************************************************************************************* 54 | ********************************************************************************************************* 55 | * INCLUDE FILES 56 | ********************************************************************************************************* 57 | ********************************************************************************************************* 58 | */ 59 | 60 | #define MICRIUM_SOURCE 61 | #define IPERF_CLIENT_MODULE 62 | #include "iperf.h" 63 | #include 64 | 65 | 66 | /* 67 | ********************************************************************************************************* 68 | ********************************************************************************************************* 69 | * MODULE 70 | * 71 | * Note(s) : (1) See 'iperf.h MODULE CONFIGURATION'. 72 | ********************************************************************************************************* 73 | ********************************************************************************************************* 74 | */ 75 | 76 | #ifdef IPERF_CLIENT_MODULE_PRESENT 77 | 78 | 79 | /* 80 | ********************************************************************************************************* 81 | ********************************************************************************************************* 82 | * LOCAL FUNCTION PROTOTYPES 83 | ********************************************************************************************************* 84 | ********************************************************************************************************* 85 | */ 86 | 87 | static void IPerf_ClientSocketInit(IPERF_TEST *p_test, 88 | IPERF_ERR *p_err); 89 | 90 | 91 | static void IPerf_ClientTCP (IPERF_TEST *p_test, 92 | IPERF_ERR *p_err); 93 | 94 | 95 | static void IPerf_ClientUDP (IPERF_TEST *p_test, 96 | IPERF_ERR *p_err); 97 | 98 | 99 | static void IPerf_ClientTxUDP_FIN (IPERF_TEST *p_test, 100 | CPU_CHAR *p_data_buf); 101 | 102 | 103 | static CPU_BOOLEAN IPerf_ClientTx (IPERF_TEST *p_test, 104 | CPU_CHAR *p_data_buf, 105 | CPU_INT16U retry_max, 106 | CPU_INT32U time_dly_ms, 107 | IPERF_ERR *p_err); 108 | 109 | 110 | static void IPerf_ClientPattern (CPU_CHAR *cp, 111 | CPU_INT16U cnt); 112 | 113 | 114 | /* 115 | ********************************************************************************************************* 116 | * IPerf_ClientStart() 117 | * 118 | * Description : (1) Process IPerf as a client : 119 | * 120 | * (a) Initialize socket 121 | * (b) Run TCP or UDP transmitter 122 | * (c) Close used socket 123 | * 124 | * 125 | * Argument(s) : p_test Pointer to a test. 126 | * ------ Argument validated in IPerf_Init(), 127 | * checked in IPerf_TestTaskHandler(). 128 | * 129 | * p_err Pointer to variable that will receive the return error code from this function : 130 | * 131 | * IPERF_ERR_NONE successfully completed. 132 | * IPERF_ERR_CLIENT_SOCK_CLOSE NOT successfully closed 133 | * 134 | * - RETURNED BY IPerf_TestGet() : - 135 | * IPERF_ERR_CLIENT_SOCK_OPEN NOT successfully opened. 136 | * IPERF_ERR_CLIENT_SOCK_BIND NOT successfully bond. 137 | * IPERF_ERR_CLIENT_SOCK_CONN NOT successfully connected. 138 | * 139 | * - RETURNED BY IPerf_TestGet() : - 140 | * IPERF_ERR_CLIENT_SOCK_TX Error on transmission. 141 | * 142 | * Return(s) : none. 143 | * 144 | * Caller(s) : IPerf_TestTaskHandler(). 145 | * 146 | * This function is an INTERNAL IPerf function & MUST NOT be called by application function(s). 147 | * 148 | * Note(s) : none. 149 | ********************************************************************************************************* 150 | */ 151 | void IPerf_ClientStart (IPERF_TEST *p_test, 152 | IPERF_ERR *p_err) 153 | { 154 | IPERF_OPT *p_opt; 155 | IPERF_CONN *p_conn; 156 | NET_ERR err; 157 | 158 | 159 | p_conn = &p_test->Conn; 160 | p_opt = &p_test->Opt; 161 | 162 | IPERF_TRACE_DBG(("\n\r-------------IPerf DBG CLIENT START-------------\n\r")); 163 | IPERF_TRACE_DBG(("Init Client socket.\n\r")); 164 | 165 | 166 | 167 | IPerf_ClientSocketInit(p_test, p_err); /* -------------------- INIT SOCK --------------------- */ 168 | 169 | if (*p_err != IPERF_ERR_NONE) { 170 | return; 171 | } 172 | 173 | 174 | /* --------------- TCP/UDP TRANSMITTER ---------------- */ 175 | if (p_opt->Protocol == IPERF_PROTOCOL_TCP) { 176 | IPerf_ClientTCP(p_test, p_err); 177 | } else if (p_opt->Protocol == IPERF_PROTOCOL_UDP) { 178 | IPerf_ClientUDP(p_test, p_err); 179 | } 180 | 181 | 182 | /* -------------------- CLOSE SOCK -------------------- */ 183 | if (p_conn->SockID != NET_SOCK_ID_NONE) { 184 | (void)NetApp_SockClose((NET_SOCK_ID) p_conn->SockID, 185 | (CPU_INT32U ) 0u, 186 | (NET_ERR *)&err); 187 | switch (err) { 188 | case NET_APP_ERR_NONE: 189 | break; 190 | 191 | 192 | case NET_APP_ERR_FAULT_TRANSITORY: 193 | case NET_APP_ERR_FAULT: 194 | case NET_APP_ERR_INVALID_ARG: 195 | default: 196 | IPERF_TRACE_DBG(("Closing socket error: %u.\n\r", (unsigned int)err)); 197 | if (*p_err == IPERF_ERR_NONE) { /* Don't erase previous err. */ 198 | *p_err = IPERF_ERR_CLIENT_SOCK_CLOSE; 199 | } 200 | break; 201 | } 202 | } 203 | 204 | IPERF_TRACE_DBG(("\n\r-------------IPerf DBG CLIENT END-------------\n\r")); 205 | } 206 | 207 | 208 | /* 209 | ********************************************************************************************************* 210 | ********************************************************************************************************* 211 | * LOCAL FUNCTIONS 212 | ********************************************************************************************************* 213 | ********************************************************************************************************* 214 | */ 215 | 216 | /* 217 | ********************************************************************************************************* 218 | * IPerf_ClientSocketInit() 219 | * 220 | * Description : (1) Initialize one socket for client use : 221 | * 222 | * (a) Open a socket 223 | * (b) If bind client is enabled , bind the socket on local address & the same port as server 224 | * (c) Connect to remote addr & port 225 | * 226 | * 227 | * Argument(s) : p_test Pointer to a test. 228 | * ------ Argument validated in IPerf_Init(), 229 | * checked in IPerf_ClientStart(), 230 | * by IPerf_TestTaskHandler(). 231 | * 232 | * p_err Pointer to variable that will receive the return error code from this function : 233 | * 234 | * IPERF_ERR_NONE socket successfully initialized 235 | * IPERF_ERR_CLIENT_SOCK_OPEN socket NOT successfully opened. 236 | * IPERF_ERR_CLIENT_SOCK_BIND socket NOT successfully bond. 237 | * IPERF_ERR_CLIENT_SOCK_CONN socket NOT successfully connected. 238 | * 239 | * Return(s) : none. 240 | * 241 | * Caller(s) : IPerf_Server_Start(). 242 | * 243 | * Note(s) : none. 244 | ********************************************************************************************************* 245 | */ 246 | 247 | static void IPerf_ClientSocketInit (IPERF_TEST *p_test, 248 | IPERF_ERR *p_err) 249 | { 250 | IPERF_OPT *p_opt; 251 | IPERF_CONN *p_conn; 252 | NET_SOCK_ID sock_id; 253 | NET_SOCK_ADDR_FAMILY addr_family; 254 | NET_ERR err; 255 | CPU_INT16U server_port; 256 | CPU_BOOLEAN cfg_succeed; 257 | #if (IPERF_CFG_CLIENT_BIND_EN == DEF_ENABLED) 258 | NET_IF_NBR if_nbr; 259 | NET_IP_ADDRS_QTY addr_tbl_size; 260 | #ifdef NET_IPv4_MODULE_EN 261 | NET_IPv4_ADDR addr_ipv4_tbl[NET_IPv4_CFG_IF_MAX_NBR_ADDR]; 262 | #endif 263 | #ifdef NET_IPv6_MODULE_EN 264 | NET_IPv6_ADDR addr_ipv6_tbl[NET_IPv6_CFG_IF_MAX_NBR_ADDR]; 265 | #endif 266 | #endif 267 | #ifdef NET_IPv4_MODULE_EN 268 | NET_IPv4_ADDR remote_addr_ipv4; 269 | #endif 270 | #ifdef NET_IPv6_MODULE_EN 271 | NET_IPv6_ADDR remote_addr_ipv6; 272 | #endif 273 | 274 | 275 | p_opt = &p_test->Opt; 276 | p_conn = &p_test->Conn; 277 | 278 | 279 | 280 | server_port = p_opt->Port; 281 | addr_family = ((p_opt->IPv4 == DEF_YES) ? (NET_SOCK_ADDR_FAMILY_IP_V4) : (NET_SOCK_ADDR_FAMILY_IP_V6)); 282 | 283 | /* --------------------- OPEN SOCK -------------------- */ 284 | IPERF_TRACE_DBG(("Socket Open ")); 285 | if (p_opt->Protocol == IPERF_PROTOCOL_UDP) { 286 | IPERF_TRACE_DBG(("UDP : ")); 287 | sock_id = NetApp_SockOpen((NET_SOCK_PROTOCOL_FAMILY) addr_family, 288 | (NET_SOCK_TYPE ) NET_SOCK_TYPE_DATAGRAM, 289 | (NET_SOCK_PROTOCOL ) NET_SOCK_PROTOCOL_UDP, 290 | (CPU_INT16U ) IPERF_OPEN_MAX_RETRY, 291 | (CPU_INT32U ) IPERF_OPEN_MAX_DLY_MS, 292 | (NET_ERR *)&err); 293 | } else { 294 | IPERF_TRACE_DBG(("TCP : ")); 295 | sock_id = NetApp_SockOpen((NET_SOCK_PROTOCOL_FAMILY) addr_family, 296 | (NET_SOCK_TYPE ) NET_SOCK_TYPE_STREAM, 297 | (NET_SOCK_PROTOCOL ) NET_SOCK_PROTOCOL_TCP, 298 | (CPU_INT16U ) IPERF_OPEN_MAX_RETRY, 299 | (CPU_INT32U ) IPERF_OPEN_MAX_DLY_MS, 300 | (NET_ERR *)&err); 301 | } 302 | switch (err) { 303 | case NET_APP_ERR_NONE: 304 | p_conn->SockID = sock_id; 305 | IPERF_TRACE_DBG(("Done, Socket ID = %d.\n\r", sock_id)); 306 | break; 307 | 308 | 309 | case NET_APP_ERR_FAULT: 310 | case NET_APP_ERR_NONE_AVAIL: 311 | case NET_APP_ERR_INVALID_ARG: 312 | default: 313 | IPERF_TRACE_DBG(("Fail, error: %u.\n\r", (unsigned int)err)); 314 | *p_err = IPERF_ERR_CLIENT_SOCK_OPEN; 315 | return; 316 | } 317 | 318 | switch (addr_family) { 319 | #ifdef NET_IPv4_MODULE_EN 320 | case NET_SOCK_PROTOCOL_FAMILY_IP_V4: 321 | remote_addr_ipv4 = NetASCII_Str_to_IPv4((CPU_CHAR *) p_opt->IP_AddrRemote, 322 | (NET_ERR *)&err); 323 | if (err != NET_ASCII_ERR_NONE) { 324 | IPERF_TRACE_DBG(("Fail, error: %u.\n\r", (unsigned int)err)); 325 | *p_err = IPERF_ERR_CLIENT_INVALID_IP_FAMILY; 326 | return; 327 | } 328 | 329 | NetApp_SetSockAddr( &p_conn->ServerAddrPort, 330 | NET_SOCK_ADDR_FAMILY_IP_V4, 331 | server_port, 332 | (CPU_INT08U *)&remote_addr_ipv4, 333 | sizeof(remote_addr_ipv4), 334 | &err); 335 | break; 336 | #endif 337 | 338 | #ifdef NET_IPv6_MODULE_EN 339 | case NET_SOCK_PROTOCOL_FAMILY_IP_V6: 340 | remote_addr_ipv6 = NetASCII_Str_to_IPv6((CPU_CHAR *) p_opt->IP_AddrRemote, 341 | (NET_ERR *)&err); 342 | if (err != NET_ASCII_ERR_NONE) { 343 | IPERF_TRACE_DBG(("Fail, error: %u.\n\r", (unsigned int)err)); 344 | *p_err = IPERF_ERR_CLIENT_INVALID_IP_FAMILY; 345 | return; 346 | } 347 | 348 | 349 | NetApp_SetSockAddr( &p_conn->ServerAddrPort, 350 | NET_SOCK_ADDR_FAMILY_IP_V6, 351 | server_port, 352 | (CPU_INT08U *)&remote_addr_ipv6, 353 | sizeof(remote_addr_ipv6), 354 | &err); 355 | break; 356 | #endif 357 | default: 358 | IPERF_TRACE_DBG(("Fail, error: %u.\n\r", (unsigned int)err)); 359 | *p_err = IPERF_ERR_CLIENT_INVALID_IP_FAMILY; 360 | return; 361 | } 362 | 363 | cfg_succeed = NetSock_CfgBlock(sock_id, NET_SOCK_BLOCK_SEL_BLOCK, &err); 364 | if (cfg_succeed != DEF_OK) { 365 | *p_err = IPERF_ERR_CLIENT_SOCK_OPT; 366 | return; 367 | } 368 | 369 | #if (IPERF_CFG_CLIENT_BIND_EN == DEF_ENABLED) 370 | 371 | if_nbr = p_conn->IF_Nbr; 372 | /* -------------------- BIND SOCK --------------------- */ 373 | Mem_Clr((void *)&p_conn->ClientAddrPort, 374 | (CPU_SIZE_T) NET_SOCK_ADDR_SIZE); 375 | 376 | switch (addr_family) { 377 | #ifdef NET_IPv4_MODULE_EN 378 | case NET_SOCK_PROTOCOL_FAMILY_IP_V4: 379 | addr_tbl_size = sizeof(NET_IPv4_ADDR); 380 | 381 | (void)NetIPv4_GetAddrHost((NET_IF_NBR ) if_nbr, 382 | (NET_IPv4_ADDR *)&addr_ipv4_tbl[0], 383 | (NET_IP_ADDRS_QTY *)&addr_tbl_size, 384 | (NET_ERR *)&err); 385 | 386 | NetApp_SetSockAddr( &p_conn->ClientAddrPort, 387 | NET_SOCK_ADDR_FAMILY_IP_V4, 388 | server_port, 389 | (CPU_INT08U *)&addr_ipv4_tbl[0], 390 | NET_IPv4_ADDR_SIZE, 391 | &err); 392 | break; 393 | #endif 394 | 395 | #ifdef NET_IPv6_MODULE_EN 396 | case NET_SOCK_PROTOCOL_FAMILY_IP_V6: 397 | addr_tbl_size = sizeof(addr_ipv6_tbl) / sizeof(NET_IPv6_ADDR); 398 | (void)NetIPv6_GetAddrHost((NET_IF_NBR ) if_nbr, 399 | (NET_IPv6_ADDR *)&addr_ipv6_tbl[0], 400 | (NET_IP_ADDRS_QTY *)&addr_tbl_size, 401 | (NET_ERR *)&err); 402 | 403 | NetApp_SetSockAddr( &p_conn->ClientAddrPort, 404 | NET_SOCK_ADDR_FAMILY_IP_V6, 405 | server_port, 406 | (CPU_INT08U *)&addr_ipv6_tbl[0], 407 | NET_IPv6_ADDR_SIZE, 408 | &err); 409 | break; 410 | #endif 411 | default: 412 | IPERF_TRACE_DBG(("Fail, error: %u.\n\r", (unsigned int)err)); 413 | *p_err = IPERF_ERR_CLIENT_INVALID_IP_FAMILY; 414 | return; 415 | } 416 | 417 | IPERF_TRACE_DBG(("Socket Bind ... ")); 418 | (void)NetApp_SockBind((NET_SOCK_ID ) p_conn->SockID, 419 | (NET_SOCK_ADDR *)&p_conn->ClientAddrPort, 420 | (NET_SOCK_ADDR_LEN) NET_SOCK_ADDR_SIZE, 421 | (CPU_INT16U ) IPERF_BIND_MAX_RETRY, 422 | (CPU_INT32U ) IPERF_BIND_MAX_DLY_MS, 423 | (NET_ERR *)&err); 424 | 425 | switch (err) { 426 | case NET_APP_ERR_NONE: 427 | IPERF_TRACE_DBG(("done\r\n\r")); 428 | break; 429 | 430 | 431 | case NET_APP_ERR_NONE_AVAIL: 432 | case NET_APP_ERR_INVALID_ARG: 433 | case NET_APP_ERR_INVALID_OP: 434 | case NET_APP_ERR_FAULT: 435 | default: 436 | IPERF_TRACE_DBG(("Fail error: %u.\n\r", (unsigned int)err)); 437 | *p_err = IPERF_ERR_CLIENT_SOCK_BIND; 438 | /* Close sock. */ 439 | (void)NetApp_SockClose((NET_SOCK_ID) p_conn->SockID, 440 | (CPU_INT32U ) 0u, 441 | (NET_ERR *)&err); 442 | return; 443 | } 444 | #endif 445 | 446 | /* ---------------- REMOTE CONNECTION ----------------- */ 447 | /* Remote IP addr for sock conn. */ 448 | IPERF_TRACE_DBG(("Socket Conn ... ")); 449 | (void)NetApp_SockConn((NET_SOCK_ID ) p_conn->SockID, 450 | (NET_SOCK_ADDR *)&p_conn->ServerAddrPort, 451 | (NET_SOCK_ADDR_LEN) NET_SOCK_ADDR_SIZE, 452 | (CPU_INT16U ) IPERF_CFG_CLIENT_CONN_MAX_RETRY, 453 | (CPU_INT32U ) IPERF_CFG_CLIENT_CONN_MAX_TIMEOUT_MS, 454 | (CPU_INT32U ) IPERF_CFG_CLIENT_CONN_MAX_DLY_MS, 455 | (NET_ERR *)&err); 456 | switch (err) { 457 | case NET_APP_ERR_NONE: 458 | IPERF_TRACE_DBG(("Done\n\r")); 459 | IPERF_TRACE_DBG(("Connected to : %s, port: %u\r\n\r", p_opt->IP_AddrRemote, 460 | (unsigned int)p_opt->Port)); 461 | break; 462 | 463 | 464 | case NET_APP_ERR_FAULT: 465 | case NET_APP_ERR_INVALID_OP: 466 | case NET_APP_ERR_NONE_AVAIL: 467 | case NET_APP_ERR_INVALID_ARG: 468 | case NET_APP_ERR_FAULT_TRANSITORY: 469 | default: 470 | IPERF_TRACE_DBG(("Fail error: %u.\n\r", (unsigned int)err)); 471 | *p_err = IPERF_ERR_CLIENT_SOCK_CONN; 472 | /* Close sock. */ 473 | (void)NetApp_SockClose((NET_SOCK_ID) p_conn->SockID, 474 | (CPU_INT32U ) 0u, 475 | (NET_ERR *)&err); 476 | return; 477 | } 478 | 479 | *p_err = IPERF_ERR_NONE; 480 | 481 | return; 482 | } 483 | 484 | 485 | /* 486 | ********************************************************************************************************* 487 | * IPerf_ClientTCP() 488 | * 489 | * Description : (1) IPerf TCP client (tranmitter): 490 | * 491 | * (a) Initialize buffer 492 | * (b) Transmit data until the end of test is reached 493 | * 494 | * 495 | * Argument(s) : p_test Pointer to a test. 496 | * ------ Argument validated in IPerf_Init(), 497 | * checked in IPerf_ClientStart(), 498 | * by IPerf_TestTaskHandler(). 499 | * 500 | * p_err Pointer to variable that will receive the return error code from this function : 501 | * 502 | * IPERF_ERR_NONE successfully transmitted. 503 | * IPERF_ERR_CLIENT_SOCK_TX NOT successfully completed. 504 | * 505 | * Return(s) : none. 506 | * 507 | * Caller(s) : IPerf_ClientStart(). 508 | * 509 | * Note(s) : none. 510 | ********************************************************************************************************* 511 | */ 512 | static void IPerf_ClientTCP (IPERF_TEST *p_test, 513 | IPERF_ERR *p_err) 514 | { 515 | IPERF_OPT *p_opt; 516 | IPERF_CONN *p_conn; 517 | IPERF_STATS *p_stats; 518 | CPU_CHAR *p_data_buf; 519 | CPU_BOOLEAN tx_done; 520 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 521 | CPU_INT16U cpu_usage; 522 | #endif 523 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 524 | IPERF_TS_MS ts_ms_prev; 525 | CPU_INT32U tx_bytes_prev; 526 | #endif 527 | NET_ERR err; 528 | 529 | 530 | 531 | p_opt = &p_test->Opt; 532 | p_conn = &p_test->Conn; 533 | p_stats = &p_test->Stats; 534 | tx_done = DEF_NO; 535 | 536 | 537 | /* ----------------- INIT BUF PATTERN ----------------- */ 538 | #if (IPERF_CFG_ALIGN_BUF_EN == DEF_ENABLED) 539 | p_data_buf = (CPU_CHAR *)NetIF_GetTxDataAlignPtr((NET_IF_NBR) p_conn->IF_Nbr, 540 | (void *)&IPerf_Buf[0], 541 | (NET_ERR *)&err); 542 | if (err != NET_IF_ERR_NONE) { 543 | p_data_buf = &IPerf_Buf[0]; 544 | } 545 | #else 546 | p_data_buf = &IPerf_Buf[0]; 547 | #endif 548 | 549 | NetSock_CfgTimeoutTxQ_Set(p_conn->SockID, IPERF_CFG_CLIENT_TCP_TX_MAX_TIMEOUT_MS, &err); 550 | 551 | IPerf_ClientPattern(p_data_buf, p_opt->BufLen); 552 | 553 | /* --------------------- TX DATA ---------------------- */ 554 | IPERF_TRACE_DBG(("------------------- TCP START SENDING -------------------\n\r")); 555 | p_stats->TS_Start_ms = IPerf_Get_TS_ms(); 556 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 557 | ts_ms_prev = p_stats->TS_Start_ms; 558 | tx_bytes_prev = 0u; 559 | #endif 560 | p_conn->Run = DEF_YES; 561 | 562 | while (tx_done == DEF_NO) { /* Loop until the end of sending process. */ 563 | tx_done = IPerf_ClientTx((IPERF_TEST *)p_test, 564 | (CPU_CHAR *)p_data_buf, 565 | (CPU_INT16U )IPERF_CLIENT_TCP_TX_MAX_RETRY, 566 | (CPU_INT32U )IPERF_CLIENT_TCP_TX_MAX_DLY_MS, 567 | (IPERF_ERR *)p_err); 568 | 569 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 570 | cpu_usage = IPerf_OS_CPU_Usage(); 571 | p_stats->CPU_UsageAvg += cpu_usage; 572 | p_stats->CPU_CalcNbr++; 573 | if (cpu_usage > p_stats->CPU_UsageMax) { 574 | p_stats->CPU_UsageMax = cpu_usage; 575 | } 576 | #endif 577 | 578 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 579 | IPerf_UpdateBandwidth(p_test, &ts_ms_prev, &tx_bytes_prev); 580 | #endif 581 | } 582 | 583 | p_conn->Run = DEF_NO; 584 | if (*p_err != IPERF_ERR_CLIENT_SOCK_TX) { 585 | IPERF_TRACE_DBG(("*************** CLIENT TCP RESULT ***************\n\r")); 586 | IPERF_TRACE_DBG(("Tx Call count = %u \n\r", (unsigned int)p_stats->NbrCalls)); 587 | IPERF_TRACE_DBG(("Tx Err count = %u \n\r", (unsigned int)p_stats->Errs)); 588 | IPERF_TRACE_DBG(("------------------- END SENDING -------------------\n\r")); 589 | *p_err = IPERF_ERR_NONE; 590 | } 591 | } 592 | 593 | 594 | /* 595 | ********************************************************************************************************* 596 | * IPerf_ClientUDP() 597 | * 598 | * Description : (1) IPerf UDP client : 599 | * 600 | * (a) Initialize test performance statistics & buffer 601 | * (b) Transmit data until the end of test is reached 602 | * (c) Transmit UDP FIN datagram to finish UDP test 603 | * 604 | * 605 | * Argument(s) : p_test Pointer to a test. 606 | * ------ Argument validated in IPerf_Init(), 607 | * checked in IPerf_ClientStart(), 608 | * by IPerf_TestTaskHandler(). 609 | * 610 | * p_err Pointer to variable that will receive the return error code from this function : 611 | * 612 | * IPERF_ERR_NONE successfully transmitted. 613 | * IPERF_ERR_CLIENT_SOCK_TX NOT successfully transmitted. 614 | * 615 | * Return(s) : none. 616 | * 617 | * Caller(s) : IPerf_TaskHandler(). 618 | * 619 | * Note(s) : none. 620 | ********************************************************************************************************* 621 | */ 622 | 623 | static void IPerf_ClientUDP (IPERF_TEST *p_test, 624 | IPERF_ERR *p_err) 625 | { 626 | IPERF_OPT *p_opt; 627 | IPERF_CONN *p_conn; 628 | IPERF_STATS *p_stats; 629 | IPERF_UDP_DATAGRAM *p_buf; /* UDP datagram buf ptr. */ 630 | CPU_CHAR *p_data_buf; 631 | CPU_INT32S pkt_id; 632 | IPERF_TS_MS ts_cur_ms; 633 | CPU_INT32U tv_sec; 634 | CPU_INT32U tv_usec; 635 | CPU_BOOLEAN tx_done; 636 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 637 | CPU_INT16U cpu_usage; 638 | #endif 639 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 640 | IPERF_TS_MS ts_ms_prev; 641 | CPU_INT32U tx_bytes_prev; 642 | #endif 643 | #if (IPERF_CFG_ALIGN_BUF_EN == DEF_ENABLED) 644 | NET_ERR err; 645 | #endif 646 | 647 | 648 | p_opt = &p_test->Opt; 649 | p_conn = &p_test->Conn; 650 | p_stats = &p_test->Stats; 651 | tx_done = DEF_NO; 652 | pkt_id = 0u; 653 | 654 | 655 | /* ----------------- INIT BUF PATTERN ----------------- */ 656 | #if (IPERF_CFG_ALIGN_BUF_EN == DEF_ENABLED) 657 | p_data_buf = (CPU_CHAR *)NetIF_GetTxDataAlignPtr((NET_IF_NBR) p_conn->IF_Nbr, 658 | (void *)&IPerf_Buf[0], 659 | (NET_ERR *)&err); 660 | if (err != NET_IF_ERR_NONE) { 661 | p_data_buf = &IPerf_Buf[0]; 662 | } 663 | #else 664 | p_data_buf = &IPerf_Buf[0]; 665 | #endif 666 | 667 | IPerf_ClientPattern(p_data_buf, p_opt->BufLen); 668 | p_buf = (IPERF_UDP_DATAGRAM *)p_data_buf; 669 | p_conn->Run = DEF_YES; 670 | 671 | 672 | /* --------------------- TX DATA ---------------------- */ 673 | IPERF_TRACE_DBG(("------------------- UDP START SENDING -------------------\n\r")); 674 | p_stats->TS_Start_ms = IPerf_Get_TS_ms(); 675 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 676 | ts_ms_prev = p_stats->TS_Start_ms; 677 | tx_bytes_prev = 0u; 678 | #endif 679 | 680 | while (tx_done == DEF_NO) { 681 | ts_cur_ms = IPerf_Get_TS_ms(); 682 | tv_sec = ts_cur_ms / DEF_TIME_NBR_mS_PER_SEC; 683 | tv_usec = (ts_cur_ms - (tv_sec * DEF_TIME_NBR_mS_PER_SEC)) * (DEF_TIME_NBR_uS_PER_SEC / DEF_TIME_NBR_mS_PER_SEC); 684 | p_buf->ID = NET_UTIL_HOST_TO_NET_32(pkt_id); /* Set UDP datagram to send. */ 685 | p_buf->TimeVar_sec = NET_UTIL_HOST_TO_NET_32(tv_sec); 686 | p_buf->TimeVar_usec = NET_UTIL_HOST_TO_NET_32(tv_usec); 687 | 688 | tx_done = IPerf_ClientTx((IPERF_TEST *)p_test, 689 | (CPU_CHAR *)p_data_buf, 690 | (CPU_INT16U )IPERF_CLIENT_UDP_TX_MAX_RETRY, 691 | (CPU_INT32U )IPERF_CLIENT_UDP_TX_MAX_DLY_MS, 692 | (IPERF_ERR *)p_err); 693 | if (*p_err == IPERF_ERR_NONE) { 694 | pkt_id++; 695 | } 696 | 697 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 698 | cpu_usage = IPerf_OS_CPU_Usage(); 699 | p_stats->CPU_UsageAvg += cpu_usage; 700 | p_stats->CPU_CalcNbr++; 701 | if (cpu_usage > p_stats->CPU_UsageMax) { 702 | p_stats->CPU_UsageMax = cpu_usage; 703 | } 704 | #endif 705 | 706 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 707 | IPerf_UpdateBandwidth(p_test, &ts_ms_prev, &tx_bytes_prev); 708 | #endif 709 | } 710 | 711 | /* -------------------- TX UDP FIN -------------------- */ 712 | ts_cur_ms = IPerf_Get_TS_ms(); 713 | tv_sec = ts_cur_ms / DEF_TIME_NBR_mS_PER_SEC; 714 | tv_usec = (ts_cur_ms - (tv_sec * DEF_TIME_NBR_mS_PER_SEC)) * (DEF_TIME_NBR_uS_PER_SEC / DEF_TIME_NBR_mS_PER_SEC); 715 | p_buf->ID = NET_UTIL_HOST_TO_NET_32(-pkt_id); /* Prepare UDP datagram FIN to send. */ 716 | p_buf->TimeVar_sec = NET_UTIL_HOST_TO_NET_32( tv_sec); 717 | p_buf->TimeVar_usec = NET_UTIL_HOST_TO_NET_32( tv_usec); 718 | p_conn->Run = DEF_NO; 719 | if (*p_err != IPERF_ERR_CLIENT_SOCK_TX) { 720 | IPerf_ClientTxUDP_FIN(p_test, p_data_buf); 721 | 722 | IPERF_TRACE_DBG(("*************** CLIENT UDP RESULT ***************\n\r")); 723 | IPERF_TRACE_DBG(("Tx Call count = %u \n\r", (unsigned int)p_stats->NbrCalls)); 724 | IPERF_TRACE_DBG(("Tx Err count = %u \n\r", (unsigned int)p_stats->Errs)); 725 | IPERF_TRACE_DBG(("*************************************************\n\r")); 726 | IPERF_TRACE_DBG(("------------------- END SENDING -------------------\n\r")); 727 | *p_err = IPERF_ERR_NONE; 728 | } 729 | 730 | #if 0 731 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 732 | KAL_Dly(IPERF_UDP_CPU_USAGE_CALC_DLY_MS); /* dly is needed to update task stats. */ 733 | p_stats->CPU_UsageMax = IPerf_OS_CPU_Usage(); 734 | p_stats->CPU_UsageAvg = IPerf_OS_CPU_Usage(); 735 | p_stats->CPU_CalcNbr++; 736 | #endif 737 | #endif 738 | } 739 | 740 | 741 | /* 742 | ********************************************************************************************************* 743 | * IPerf_ClientTxUDP_FIN() 744 | * 745 | * Description : (1) Transmit UDP datagram FIN (end of UDP test) & receive UDP FINACK from server : 746 | * 747 | * (a) Transmit UDP client datagram header FIN 748 | * (b) Receive UDP FINACK from server 749 | * 750 | * 751 | * Argument(s) : p_test Pointer to a test. 752 | * ------ Argument validated in IPerf_Init(), 753 | * checked in IPerf_ClientUDP(), 754 | * by IPerf_TestTaskHandler(). 755 | * 756 | * p_data_buf Pointer to data to transmit. 757 | * ---------- Argument validated in IPerf_ClientUDP(). 758 | * 759 | * Return(s) : none. 760 | * 761 | * Caller(s) : IPerf_ClientUDP(). 762 | * 763 | * Note(s) : (1) $$$$ Server send UDP statistic into the FINACK paket (bytes reveived, stop time, 764 | * lost count, out of order count, last paket id received and jitter). Presently, 765 | * this data is not saved into the test statistics. 766 | ********************************************************************************************************* 767 | */ 768 | 769 | static void IPerf_ClientTxUDP_FIN (IPERF_TEST *p_test, 770 | CPU_CHAR *p_data_buf) 771 | { 772 | IPERF_CONN *p_conn; 773 | IPERF_STATS *p_stats; 774 | CPU_INT08U data_len; 775 | CPU_INT08U tx_ctr; 776 | CPU_INT16U tx_err_ctr; 777 | CPU_INT32S data_received; 778 | CPU_BOOLEAN done; 779 | NET_SOCK_ADDR_LEN addr_len_server; 780 | NET_ERR err; 781 | 782 | 783 | p_conn = &p_test->Conn; 784 | p_stats = &p_test->Stats; 785 | data_len = 128u; 786 | tx_ctr = 0u; 787 | tx_err_ctr = 0u; 788 | done = DEF_NO; 789 | 790 | IPERF_TRACE_DBG(("Sending FIN ACK:")); 791 | 792 | while (done == DEF_NO) { /* Loop until rx'd UDP FINACK or tx'd 10 time. */ 793 | 794 | 795 | /* ------------------ TX CLIENT HDR ------------------- */ 796 | addr_len_server = sizeof(p_conn->ServerAddrPort); 797 | (void)NetApp_SockTx((NET_SOCK_ID ) p_conn->SockID, 798 | (void *) p_data_buf, 799 | (CPU_INT16U ) data_len, 800 | (CPU_INT16S ) NET_SOCK_FLAG_NONE, 801 | (NET_SOCK_ADDR *)&p_conn->ServerAddrPort, 802 | (NET_SOCK_ADDR_LEN) addr_len_server, 803 | (CPU_INT16U ) IPERF_CLIENT_UDP_TX_MAX_RETRY, 804 | (CPU_INT32U ) 0, 805 | (CPU_INT32U ) IPERF_CLIENT_UDP_TX_MAX_DLY_MS, 806 | (NET_ERR *)&err); 807 | switch (err) { 808 | case NET_APP_ERR_NONE: /* Tx successful. */ 809 | tx_ctr++; /* Inc tx cnt. */ 810 | IPERF_TRACE_DBG((".")); 811 | break; 812 | 813 | 814 | case NET_APP_ERR_CONN_CLOSED: /* Err, exit sending process. */ 815 | case NET_APP_ERR_FAULT: 816 | case NET_APP_ERR_INVALID_ARG: 817 | case NET_APP_ERR_INVALID_OP: 818 | tx_ctr = IPERF_SERVER_UDP_TX_FINACK_COUNT; 819 | break; 820 | 821 | 822 | case NET_ERR_TX: 823 | default: 824 | IPERF_TRACE_DBG(("Tx error: %u\n\r", (unsigned int)err)); 825 | tx_err_ctr++; 826 | break; 827 | } 828 | 829 | 830 | /* -------------- RX SERVER UDP FIN ACK --------------- */ 831 | if (err == NET_APP_ERR_NONE) { 832 | data_received = NetApp_SockRx((NET_SOCK_ID ) p_conn->SockID, 833 | (void *) p_data_buf, 834 | (CPU_INT16U ) IPERF_UDP_BUF_LEN_MAX, 835 | (CPU_INT16U ) 0u, 836 | (CPU_INT16S ) NET_SOCK_FLAG_NONE, 837 | (NET_SOCK_ADDR *)&p_conn->ServerAddrPort, 838 | (NET_SOCK_ADDR_LEN *)&addr_len_server, 839 | (CPU_INT16U ) IPERF_RX_UDP_FINACK_MAX_RETRY, 840 | (CPU_INT32U ) IPERF_RX_UDP_FINACK_MAX_TIMEOUT_MS, 841 | (CPU_INT32U ) IPERF_RX_UDP_FINACK_MAX_DLY_MS, 842 | (NET_ERR *)&err); 843 | if (data_received > 0u) { 844 | p_stats->UDP_EndErr = DEF_NO; 845 | IPERF_TRACE_DBG(("\n\rReceived UDP FINACK from server.\n\r")); 846 | return; /* Rx'd server UDP FINACK, UDP test done. */ 847 | /* $$$$ Sto rx'd stats of server (see Note #1). */ 848 | } 849 | } 850 | 851 | if (tx_ctr == IPERF_SERVER_UDP_TX_FINACK_COUNT) { 852 | p_stats->UDP_EndErr = DEF_YES; 853 | IPERF_TRACE_DBG(("\n\rSent %u UDP FIN and did not receive UDP FINACK from server.\n\r", (unsigned int)IPERF_SERVER_UDP_TX_FINACK_COUNT)); 854 | done = DEF_YES; 855 | } else if (tx_err_ctr > IPERF_SERVER_UDP_TX_FINACK_ERR_MAX) { 856 | p_stats->UDP_EndErr = DEF_YES; 857 | IPERF_TRACE_DBG(("\n\rTx errors exceed maximum, %u FIN ACK sent\n\r", (unsigned int)tx_ctr)); 858 | done = DEF_YES; 859 | } 860 | } 861 | } 862 | 863 | 864 | /* 865 | ********************************************************************************************************* 866 | * IPerf_ClientTx() 867 | * 868 | * Description : Transmit data to socket until the end of test or entire buffer is sent. 869 | * 870 | * (a) Handle the end of test. 871 | * (b) If test not done, transmit data 872 | * 873 | * 874 | * Argument(s) : p_test Pointer to a test. 875 | * ------ Argument validated in IPerf_Init(), 876 | * checked in IPerf_ClientTCP(), 877 | * checked in IPerf_ClientUDP(), 878 | * by IPerf_TestTaskHandler(). 879 | * 880 | * p_data_buf Pointer to data to transmit. 881 | * ---------- Argument validated in IPerf_ClientTCP(), 882 | * IPerf_ClientUDP(). 883 | * 884 | * p_err Pointer to variable that will receive the return error code from this function : 885 | * 886 | * IPERF_ERR_NONE Transmit completed successfully, 887 | * IPERF_ERR_CLIENT_SOCK_TX Transmit NOT completed successfully. 888 | * 889 | * Return(s) : DEF_YES test completed, 890 | * DEF_NO test NOT completed. 891 | * 892 | * 893 | * Caller(s) : IPerf_ClientTCP(); 894 | * IPerf_ClientUDP(). 895 | ********************************************************************************************************* 896 | */ 897 | static CPU_BOOLEAN IPerf_ClientTx (IPERF_TEST *p_test, 898 | CPU_CHAR *p_data_buf, 899 | CPU_INT16U retry_max, 900 | CPU_INT32U time_dly_ms, 901 | IPERF_ERR *p_err) 902 | { 903 | IPERF_OPT *p_opt; 904 | IPERF_CONN *p_conn; 905 | IPERF_STATS *p_stats; 906 | CPU_INT16U tx_buf_len; 907 | CPU_INT16U tx_len; 908 | CPU_INT16U tx_len_tot; 909 | CPU_INT16U buf_len; 910 | CPU_BOOLEAN test_done; 911 | IPERF_TS_MS ts_cur; 912 | IPERF_TS_MS ts_max; 913 | IPERF_TS_MS ts_ms_delta; 914 | NET_SOCK_ADDR_LEN addr_len_server; 915 | NET_ERR err; 916 | 917 | 918 | p_opt = &p_test->Opt; 919 | p_conn = &p_test->Conn; 920 | p_stats = &p_test->Stats; 921 | tx_len_tot = 0u; 922 | test_done = DEF_NO; 923 | buf_len = p_opt->BufLen; 924 | addr_len_server = sizeof(p_conn->ServerAddrPort); 925 | *p_err = IPERF_ERR_NONE; 926 | 927 | while ((tx_len_tot < buf_len) && /* Loop until tx tot len < buf len ... */ 928 | (test_done == DEF_NO) ) { /* ... & test NOT done. */ 929 | 930 | 931 | 932 | /* --------------- HANDLING END OF TEST --------------- */ 933 | if (p_opt->Duration_ms > 0u) { 934 | ts_cur = IPerf_Get_TS_ms(); /* Tx until time duration is not reached. */ 935 | ts_max = IPerf_Get_TS_Max_ms(); 936 | if (ts_cur >= p_stats->TS_Start_ms) { 937 | ts_ms_delta = ts_cur - p_stats->TS_Start_ms; 938 | } else { 939 | ts_ms_delta = ts_cur + (ts_max - p_stats->TS_Start_ms); 940 | } 941 | 942 | 943 | if ((ts_ms_delta >= (ts_max - 100u)) || 944 | (ts_ms_delta >= p_opt->Duration_ms)) { 945 | p_stats->TS_End_ms = ts_cur; 946 | test_done = DEF_YES; 947 | } 948 | 949 | } else if (p_stats->Bytes >= p_opt->BytesNbr) { 950 | p_stats->TS_End_ms = IPerf_Get_TS_ms(); 951 | test_done = DEF_YES; 952 | } 953 | 954 | /* --------------------- TX DATA ---------------------- */ 955 | if (test_done == DEF_NO) { 956 | tx_buf_len = buf_len - tx_len_tot; 957 | p_stats->NbrCalls++; 958 | tx_len = NetApp_SockTx((NET_SOCK_ID ) p_conn->SockID, 959 | (void *) p_data_buf, 960 | (CPU_INT16U ) tx_buf_len, 961 | (CPU_INT16S ) NET_SOCK_FLAG_NONE, 962 | (NET_SOCK_ADDR *)&p_conn->ServerAddrPort, 963 | (NET_SOCK_ADDR_LEN) addr_len_server, 964 | (CPU_INT16U ) retry_max, 965 | (CPU_INT32U ) 0, 966 | (CPU_INT32U ) time_dly_ms, 967 | (NET_ERR *)&err); 968 | if (tx_len > 0) { /* If tx len > 0, ... */ 969 | tx_len_tot += tx_len; /* ... inc tot tx len & bytes tx'd. */ 970 | p_stats->Bytes += tx_len; 971 | } 972 | 973 | switch (err) { 974 | case NET_APP_ERR_NONE: 975 | break; 976 | 977 | 978 | case NET_ERR_TX: /* If transitory tx err, ... */ 979 | p_stats->TransitoryErrCnts++; /* ... inc tot TransitoryErrCnts. */ 980 | break; 981 | 982 | 983 | case NET_APP_ERR_FAULT: 984 | case NET_APP_ERR_CONN_CLOSED: 985 | case NET_APP_ERR_INVALID_OP: 986 | case NET_APP_ERR_INVALID_ARG: 987 | default: 988 | p_stats->Errs++; 989 | if ((p_opt->Protocol == IPERF_PROTOCOL_UDP ) && 990 | (p_opt->BufLen > IPERF_UDP_BUF_LEN_MAX)) { 991 | *p_err = IPERF_ERR_CLIENT_SOCK_TX_INV_ARG; 992 | } else { 993 | *p_err = IPERF_ERR_CLIENT_SOCK_TX; 994 | } 995 | test_done = DEF_YES; 996 | IPERF_TRACE_DBG(("Tx fatal Err : %u\n\r", (unsigned int)err)); 997 | break; 998 | } 999 | } 1000 | } 1001 | 1002 | return (test_done); 1003 | } 1004 | 1005 | 1006 | /* 1007 | ********************************************************************************************************* 1008 | * IPerf_ClientPattern() 1009 | * 1010 | * Description : Fill a buffer with standard IPerf buffer pattern. 1011 | * 1012 | * Argument(s) : p_buf Pointer to a buffer to fill. 1013 | * ------ Argument validated in IPerf_ClientTCP(), 1014 | * validated in IPerf_ClientUDP(). 1015 | * 1016 | * buf_len Buffer lenght. 1017 | * 1018 | * Return(s) : none. 1019 | * 1020 | * Caller(s) : IPerf_ClientTCP(), 1021 | * IPerf_ClientUDP(). 1022 | * 1023 | * Note(s) : none. 1024 | ********************************************************************************************************* 1025 | */ 1026 | 1027 | static void IPerf_ClientPattern (CPU_CHAR *p_buf, 1028 | CPU_INT16U buf_len) 1029 | { 1030 | CPU_CHAR *p_buf_wr; 1031 | 1032 | 1033 | p_buf_wr = p_buf; 1034 | while (buf_len-- > 0u) { 1035 | *p_buf_wr = (CPU_CHAR)((buf_len % 10u) + '0'); 1036 | p_buf_wr++; 1037 | } 1038 | } 1039 | 1040 | 1041 | /* 1042 | ********************************************************************************************************* 1043 | ********************************************************************************************************* 1044 | * MODULE END 1045 | * 1046 | * Note(s) : (1) See 'MODULE'. 1047 | ********************************************************************************************************* 1048 | ********************************************************************************************************* 1049 | */ 1050 | 1051 | #endif /* End of IPerf client module include (see Note #1). */ 1052 | 1053 | -------------------------------------------------------------------------------- /Source/iperf-s.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/IPerf 4 | * TCP-IP Transfer Measurement Utility 5 | * 6 | * Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * IPERF SERVER 21 | * 22 | * Filename : iperf-s.c 23 | * Version : V2.04.00 24 | ********************************************************************************************************* 25 | * Note(s) : (1) Assumes uC/TCP-IP V2.05 (or more recent version) is included in the project build. 26 | * 27 | * (2) (a) (1) uC/IPerf is designed to work with NLANR IPerf 2.0.2 or higher. 28 | * 29 | * (2) uC/IPerf should be compatible with kPerf or jPerf using IPerf 2.0.2 or higher. 30 | * 31 | * (b) Supports NLANR Iperf with the following restrictions/constraints : 32 | * 33 | * (1) TCP: 34 | * (A) Multi-threaded NOT supported on both mode 35 | * (B) Measure bandwith Supported on both mode 36 | * (C) Report MSS/MTU size & observed read sizes NOT supported on both mode 37 | * (D) Support for TCP window size via socket buffer Supported on server mode 38 | * 39 | * (2) UDP: 40 | * (A) Multi-threaded NOT supported on both mode 41 | * (B) Create UDP streams of specified bandwidth NOT supported on client mode 42 | * (C) Measure packet loss Supported on server mode 43 | * (D) Measure delay jitter NOT supported on both mode 44 | * (E) Multicast capable NOT supported on both mode 45 | * 46 | * (c) More information about NLANR IPerf can be obtained online at 47 | * http://www.onl.wustl.edu/restricted/iperf.html. 48 | ********************************************************************************************************* 49 | */ 50 | 51 | /* 52 | ********************************************************************************************************* 53 | ********************************************************************************************************* 54 | * INCLUDE FILES 55 | ********************************************************************************************************* 56 | ********************************************************************************************************* 57 | */ 58 | 59 | #define MICRIUM_SOURCE 60 | #define IPERF_SERVER_MODULE 61 | #include "iperf.h" 62 | #include 63 | 64 | #ifdef NET_IPv4_MODULE_EN 65 | #include 66 | #endif 67 | #ifdef NET_IPv6_MODULE_EN 68 | #include 69 | #endif 70 | 71 | #include 72 | #include 73 | #include 74 | 75 | /* 76 | ********************************************************************************************************* 77 | ********************************************************************************************************* 78 | * MODULE 79 | * 80 | * Note(s) : (1) See 'iperf.h MODULE CONFIGURATION'. 81 | ********************************************************************************************************* 82 | ********************************************************************************************************* 83 | */ 84 | 85 | #ifdef IPERF_SERVER_MODULE_PRESENT 86 | 87 | 88 | /* 89 | ********************************************************************************************************* 90 | * LOCAL FUNCTION PROTOTYPES 91 | ********************************************************************************************************* 92 | */ 93 | 94 | static void IPerf_ServerSockInit (IPERF_TEST *p_test, 95 | IPERF_ERR *p_err); 96 | 97 | static void IPerf_ServerTCP (IPERF_TEST *p_test, 98 | IPERF_ERR *p_err); 99 | 100 | static void IPerf_ServerRxWinSizeSet(NET_SOCK_ID sock_id, 101 | CPU_INT16U win_size, 102 | IPERF_ERR *p_err); 103 | 104 | static void IPerf_ServerUDP (IPERF_TEST *p_test, 105 | IPERF_ERR *p_err); 106 | 107 | static void IPerf_ServerUDP_FINACK (IPERF_TEST *p_test, 108 | CPU_CHAR *p_data_buf); 109 | 110 | static CPU_BOOLEAN IPerf_ServerRxPkt (IPERF_TEST *p_test, 111 | NET_SOCK_ID sock_id, 112 | CPU_CHAR *p_data_buf, 113 | CPU_INT16U retry_max, 114 | IPERF_ERR *p_err); 115 | 116 | 117 | /* 118 | ********************************************************************************************************* 119 | * IPerf_ServerStart() 120 | * 121 | * Description : (1) IPerf as a server main loop : 122 | * 123 | * (a) Initialize socket 124 | * (b) Run IPerf as TCP/UDP server 125 | * (c) Close socket used 126 | * 127 | * 128 | * Argument(s) : p_test Pointer to a test. 129 | * ------ Argument validated in IPerf_Init(), 130 | * checked in IPerf_TestTaskHandler(). 131 | * 132 | * p_err Pointer to variable that will receive the return error code from this function : 133 | * 134 | * IPERF_ERR_NONE socket successfully. 135 | * IPERF_ERR_SERVER_SOCK_OPEN socket NOT successfully opened. 136 | * IPERF_ERR_SERVER_SOCK_BIND socket NOT successfully bond. 137 | * IPERF_ERR_SERVER_SOCK_LISTEN socket NOT successfully listened. 138 | * IPERF_ERR_SERVER_SOCK_ACCEPT NOT successfully accepted. 139 | * IPERF_ERR_SERVER_WIN_SIZE NOT successfully set windows size. 140 | * IPERF_ERR_SERVER_SOCK_CLOSE NOT successfully closed. 141 | * 142 | * Return(s) : none. 143 | * 144 | * Caller(s) : IPerf_TestTaskHandler(). 145 | * 146 | * This function is an INTERNAL IPerf function & MUST NOT be called by application function(s). 147 | * 148 | * Note(s) : none. 149 | ********************************************************************************************************* 150 | */ 151 | void IPerf_ServerStart (IPERF_TEST *p_test, 152 | IPERF_ERR *p_err) 153 | { 154 | IPERF_OPT *p_opt; 155 | IPERF_CONN *p_conn; 156 | CPU_BOOLEAN run; 157 | NET_ERR err; 158 | 159 | 160 | IPERF_TRACE_INFO(("\n\r------------- IPerf SERVER START -------------\n\r")); 161 | IPERF_TRACE_DBG(("Init server socket\n\r")); 162 | 163 | 164 | /* ------------- INIT SOCK / OPEN & BIND -------------- */ 165 | IPerf_ServerSockInit(p_test, p_err); 166 | if (*p_err != IPERF_ERR_NONE) { 167 | return; 168 | } 169 | 170 | IPERF_TRACE_INFO(("IPerf Server Task : \n\r")); 171 | p_conn = &p_test->Conn; 172 | p_opt = &p_test->Opt; 173 | 174 | run = DEF_YES; 175 | 176 | 177 | /* --------------- RUN IPERF TCP/UDP RX --------------- */ 178 | while (run == DEF_YES) { 179 | p_test->Status = IPERF_TEST_STATUS_RUNNING; 180 | if (p_opt->Protocol == IPERF_PROTOCOL_TCP) { 181 | IPerf_ServerTCP(p_test, p_err); 182 | } else { 183 | IPerf_ServerUDP(p_test, p_err); 184 | } 185 | 186 | if (*p_err != IPERF_ERR_NONE) { 187 | p_test->Err = *p_err; 188 | run = DEF_NO; 189 | } 190 | 191 | if (p_opt->Persistent == DEF_DISABLED) { 192 | run = DEF_NO; 193 | } 194 | } 195 | 196 | 197 | /* -------------------- CLOSE SOCK -------------------- */ 198 | IPERF_TRACE_DBG(("Closing socket.\n\r")); 199 | if (p_conn->SockID != NET_SOCK_ID_NONE) { 200 | (void)NetApp_SockClose((NET_SOCK_ID) p_conn->SockID, 201 | (CPU_INT32U ) 0u, 202 | (NET_ERR *)&err); 203 | if (err != NET_APP_ERR_NONE) { 204 | IPERF_TRACE_DBG(("Sock close error : %u\n\r", (unsigned int)err)); 205 | } 206 | } 207 | 208 | IPERF_TRACE_INFO(("\n\r------------- IPerf SERVER ENDED -------------\n\r")); 209 | } 210 | 211 | 212 | /* 213 | ********************************************************************************************************* 214 | ********************************************************************************************************* 215 | * LOCAL FUNCTIONS 216 | ********************************************************************************************************* 217 | ********************************************************************************************************* 218 | */ 219 | 220 | /* 221 | ********************************************************************************************************* 222 | * IPerf_ServerSockInit() 223 | * 224 | * Description : (1) Initialize one socket for sever use : 225 | * 226 | * (a) Open socket for incoming connection 227 | * (b) Bind socket on any address & current test's options port 228 | * (c) If TCP server, do a socket listen. 229 | * 230 | * 231 | * Argument(s) : p_test Pointer to a test. 232 | * ------ Argument validated in IPerf_Init(), 233 | * checked in IPerf_ServerStart(), 234 | * by IPerf_TestTaskHandler(). 235 | * 236 | * p_err Pointer to variable that will receive the return error code from this function : 237 | * 238 | * IPERF_ERR_NONE socket successfully initialized. 239 | * IPERF_ERR_SERVER_SOCK_OPEN socket NOT successfully opened. 240 | * IPERF_ERR_SERVER_SOCK_BIND socket NOT successfully bond. 241 | * IPERF_ERR_SERVER_SOCK_LISTEN socket NOT successfully listened. 242 | * 243 | * 244 | * Return(s) : none. 245 | * 246 | * 247 | * Caller(s) : IPerf_ServerStart(). 248 | * 249 | * Note(s) : none. 250 | ********************************************************************************************************* 251 | */ 252 | 253 | static void IPerf_ServerSockInit (IPERF_TEST *p_test, 254 | IPERF_ERR *p_err) 255 | { 256 | IPERF_OPT *p_opt; 257 | IPERF_CONN *p_conn; 258 | NET_SOCK_ID sock_id; 259 | NET_SOCK_ADDR sock_addr_server; 260 | NET_SOCK_ADDR_FAMILY addr_family; 261 | CPU_INT16U server_port; 262 | CPU_BOOLEAN cfg_succeed; 263 | NET_ERR err; 264 | #ifdef NET_IPv4_MODULE_EN 265 | NET_IPv4_ADDR addr_any_ipv4; 266 | #endif 267 | 268 | p_opt = &p_test->Opt; 269 | p_conn = &p_test->Conn; 270 | 271 | server_port = p_opt->Port; 272 | addr_family = ((p_opt->IPv4 == DEF_YES) ? (NET_SOCK_ADDR_FAMILY_IP_V4) : (NET_SOCK_ADDR_FAMILY_IP_V6)); 273 | 274 | /* -------------------- OPEN SOCK --------------------- */ 275 | IPERF_TRACE_DBG(("Server SockOpen ")); 276 | if (p_opt->Protocol == IPERF_PROTOCOL_UDP) { 277 | IPERF_TRACE_DBG(("UDP ... ")); 278 | sock_id = NetApp_SockOpen((NET_SOCK_PROTOCOL_FAMILY) addr_family, 279 | (NET_SOCK_TYPE ) NET_SOCK_TYPE_DATAGRAM, 280 | (NET_SOCK_PROTOCOL ) NET_SOCK_PROTOCOL_UDP, 281 | (CPU_INT16U ) IPERF_OPEN_MAX_RETRY, 282 | (CPU_INT32U ) IPERF_OPEN_MAX_DLY_MS, 283 | (NET_ERR *)&err); 284 | } else { 285 | IPERF_TRACE_DBG(("TCP ... ")); 286 | sock_id = NetApp_SockOpen((NET_SOCK_PROTOCOL_FAMILY) addr_family, 287 | (NET_SOCK_TYPE ) NET_SOCK_TYPE_STREAM, 288 | (NET_SOCK_PROTOCOL ) NET_SOCK_PROTOCOL_TCP, 289 | (CPU_INT16U ) IPERF_OPEN_MAX_RETRY, 290 | (CPU_INT32U ) IPERF_OPEN_MAX_DLY_MS, 291 | (NET_ERR *)&err); 292 | } 293 | switch (err) { 294 | case NET_APP_ERR_NONE: 295 | IPERF_TRACE_DBG(("done.\n\r")); 296 | break; 297 | 298 | 299 | case NET_APP_ERR_FAULT: 300 | case NET_APP_ERR_NONE_AVAIL: 301 | case NET_APP_ERR_INVALID_ARG: 302 | default: 303 | IPERF_TRACE_DBG(("Fail, error : %u.\n\r", (unsigned int)err)); 304 | *p_err = IPERF_ERR_SERVER_SOCK_OPEN; 305 | return; 306 | } 307 | 308 | cfg_succeed = NetSock_CfgBlock(sock_id, NET_SOCK_BLOCK_SEL_BLOCK, &err); 309 | if (cfg_succeed != DEF_OK) { 310 | *p_err = IPERF_ERR_SERVER_SOCK_OPT; 311 | return; 312 | } 313 | 314 | /* -------------------- BIND SOCK --------------------- */ 315 | Mem_Clr((void *)&sock_addr_server, 316 | (CPU_SIZE_T) NET_SOCK_ADDR_SIZE); 317 | 318 | switch (addr_family) { 319 | #ifdef NET_IPv4_MODULE_EN 320 | case NET_SOCK_PROTOCOL_FAMILY_IP_V4: 321 | addr_any_ipv4 = NET_IPv4_ADDR_NONE; 322 | NetApp_SetSockAddr( &sock_addr_server, 323 | NET_SOCK_ADDR_FAMILY_IP_V4, 324 | server_port, 325 | (CPU_INT08U *)&addr_any_ipv4, 326 | NET_IPv4_ADDR_SIZE, 327 | &err); 328 | break; 329 | #endif 330 | 331 | #ifdef NET_IPv6_MODULE_EN 332 | case NET_SOCK_PROTOCOL_FAMILY_IP_V6: 333 | 334 | NetApp_SetSockAddr( &sock_addr_server, 335 | NET_SOCK_ADDR_FAMILY_IP_V6, 336 | server_port, 337 | (CPU_INT08U *)&NET_IPv6_ADDR_ANY, 338 | NET_IPv6_ADDR_SIZE, 339 | &err); 340 | break; 341 | #endif 342 | default: 343 | IPERF_TRACE_DBG(("Fail, error: %u.\n\r", (unsigned int)err)); 344 | *p_err = IPERF_ERR_SERVER_INVALID_IP_FAMILY; 345 | return; 346 | } 347 | 348 | 349 | IPERF_TRACE_DBG(("Server Sock Bind ... ")); 350 | (void)NetApp_SockBind((NET_SOCK_ID ) sock_id, 351 | (NET_SOCK_ADDR *)&sock_addr_server, 352 | (NET_SOCK_ADDR_LEN) NET_SOCK_ADDR_SIZE, 353 | (CPU_INT16U ) IPERF_BIND_MAX_RETRY, 354 | (CPU_INT32U ) IPERF_BIND_MAX_DLY_MS, 355 | (NET_ERR *)&err); 356 | switch (err) { 357 | case NET_APP_ERR_NONE: 358 | p_conn->SockID = sock_id; 359 | Mem_Copy(&p_conn->ServerAddrPort, &sock_addr_server, NET_SOCK_ADDR_SIZE); 360 | IPERF_TRACE_DBG(("done.\n\r")); 361 | break; 362 | 363 | 364 | case NET_APP_ERR_FAULT: 365 | case NET_APP_ERR_NONE_AVAIL: 366 | case NET_APP_ERR_INVALID_ARG: 367 | default: 368 | IPERF_TRACE_DBG(("Fail error : %u.\n\r", (unsigned int)err)); 369 | (void)NetApp_SockClose((NET_SOCK_ID) sock_id, 370 | (CPU_INT32U ) 0u, 371 | (NET_ERR *)&err); 372 | if (err != NET_APP_ERR_NONE) { 373 | IPERF_TRACE_DBG(("Close socket error : %u.\n\r", (unsigned int)err)); 374 | } 375 | *p_err = IPERF_ERR_SERVER_SOCK_BIND; 376 | return; 377 | } 378 | 379 | 380 | 381 | if (p_opt->Protocol == IPERF_PROTOCOL_TCP) { /* Only TCP req a sock listen & a TCP Rx window size. */ 382 | IPERF_TRACE_DBG(("Server listen ... ")); /* ------------------- SOCK LISTEN -------------------- */ 383 | (void)NetApp_SockListen((NET_SOCK_ID ) sock_id, 384 | (NET_SOCK_Q_SIZE) IPERF_SERVER_TCP_CONN_Q_SIZE, 385 | (NET_ERR *)&err); 386 | switch (err) { 387 | case NET_APP_ERR_NONE: 388 | IPERF_TRACE_DBG(("done.\n\r")); 389 | break; 390 | 391 | 392 | case NET_APP_ERR_FAULT: 393 | case NET_APP_ERR_INVALID_OP: 394 | case NET_APP_ERR_INVALID_ARG: 395 | case NET_APP_ERR_FAULT_TRANSITORY: 396 | default: 397 | IPERF_TRACE_DBG(("Fail error : %u.\n\r", (unsigned int)err)); 398 | (void)NetApp_SockClose((NET_SOCK_ID) sock_id, 399 | (CPU_INT32U ) 0u, 400 | (NET_ERR *)&err); 401 | if (err != NET_APP_ERR_NONE) { 402 | IPERF_TRACE_DBG(("Close socket error : %u.\n\r", (unsigned int)err)); 403 | } 404 | *p_err = IPERF_ERR_SERVER_SOCK_LISTEN; 405 | return; 406 | } 407 | 408 | 409 | /* ----------------- SET WINDOW SIZE ------------------ */ 410 | IPERF_TRACE_DBG(("Set accepted socket window size... ")); 411 | IPerf_ServerRxWinSizeSet(sock_id, p_opt->WinSize, p_err); 412 | if (*p_err != IPERF_ERR_NONE) { 413 | IPERF_TRACE_DBG(("Error\n\r")); 414 | return; 415 | } 416 | IPERF_TRACE_DBG(("Done\n\r")); 417 | } 418 | 419 | 420 | 421 | *p_err = IPERF_ERR_NONE; 422 | } 423 | 424 | 425 | /* 426 | ********************************************************************************************************* 427 | * IPerf_ServerTCP() 428 | * 429 | * Description : (1) IPerf TCP server : 430 | * 431 | * (a) Wait for client connection (socket accept incoming connection) 432 | * (b) Set rx window size 433 | * (c) Receive packet until socket close received from client 434 | * (d) Close accepted socket 435 | * 436 | * 437 | * Argument(s) : p_test Pointer to a test. 438 | * ------ Argument validated in IPerf_Init(), 439 | * checked in IPerf_ServerStart(), 440 | * by IPerf_TestTaskHandler(). 441 | * 442 | * p_err Pointer to variable that will receive the return error code from this function 443 | * 444 | * IPERF_ERR_NONE Test successfully completed. 445 | * IPERF_ERR_SERVER_SOCK_ACCEPT NOT successfully accepted client connection. 446 | * IPERF_ERR_SERVER_SOCK_CLOSE NOT successfully closed socket accepted. 447 | * 448 | * - RETURNED BY IPerf_ServerRxWinSizeSet() : -- 449 | * IPERF_ERR_SERVER_WIN_SIZE Windows size can't be set. 450 | * 451 | * ----- RETURNED BY IPerf_ServerRxPkt() : ----- 452 | * IPERF_ERR_SERVER_SOCK_RX Fatal error with rx socket. 453 | * 454 | * Return(s) : none. 455 | * 456 | * Caller(s) : IPerf_ServerStart(). 457 | * 458 | * Note(s) : none. 459 | ********************************************************************************************************* 460 | */ 461 | 462 | static void IPerf_ServerTCP (IPERF_TEST *p_test, 463 | IPERF_ERR *p_err) 464 | { 465 | IPERF_CONN *p_conn; 466 | CPU_CHAR *p_data_buf; 467 | CPU_BOOLEAN rx_done; 468 | NET_SOCK_ID sock_id; 469 | NET_SOCK_ADDR_LEN addr_len_client; 470 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 471 | CPU_INT16U cpu_usage; 472 | #endif 473 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 474 | CPU_BOOLEAN rx_started; 475 | IPERF_TS_MS ts_ms_prev; 476 | CPU_INT32U rx_bytes_prev; 477 | #endif 478 | #if ((IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) || \ 479 | (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED)) 480 | IPERF_STATS *p_stats; 481 | #endif 482 | NET_ERR err; 483 | 484 | 485 | p_conn = &p_test->Conn; 486 | p_conn->Run = DEF_NO; 487 | 488 | /* ------------------- SOCK ACCEPT -------------------- */ 489 | IPERF_TRACE_DBG(("TCP Server Accept ... ")); 490 | 491 | p_test->Status = IPERF_TEST_STATUS_RUNNING; 492 | addr_len_client = sizeof(p_conn->ClientAddrPort); 493 | sock_id = NetApp_SockAccept((NET_SOCK_ID ) p_conn->SockID, 494 | (NET_SOCK_ADDR *)&p_conn->ClientAddrPort, 495 | (NET_SOCK_ADDR_LEN *)&addr_len_client, 496 | (CPU_INT16U ) IPERF_CFG_SERVER_ACCEPT_MAX_RETRY, 497 | (CPU_INT32U ) IPERF_CFG_SERVER_ACCEPT_MAX_TIMEOUT_MS, 498 | (CPU_INT32U ) IPERF_CFG_SERVER_ACCEPT_MAX_DLY_MS, 499 | (NET_ERR *)&err); 500 | switch (err) { 501 | case NET_APP_ERR_NONE: 502 | p_conn->SockID_TCP_Server = sock_id; 503 | *p_err = IPERF_ERR_NONE; 504 | IPERF_TRACE_DBG(("Done.\n\r")); 505 | break; 506 | 507 | 508 | case NET_APP_ERR_NONE_AVAIL: 509 | case NET_APP_ERR_FAULT_TRANSITORY: 510 | case NET_APP_ERR_FAULT: 511 | case NET_APP_ERR_INVALID_OP: 512 | case NET_APP_ERR_INVALID_ARG: 513 | default: 514 | *p_err = IPERF_ERR_SERVER_SOCK_ACCEPT; 515 | IPERF_TRACE_INFO(("Error : %u.\n\r", (unsigned int)err)); 516 | return; 517 | } 518 | 519 | 520 | /* --------------------- RX PKTS ---------------------- */ 521 | #if (IPERF_CFG_ALIGN_BUF_EN == DEF_ENABLED) 522 | p_data_buf = (CPU_CHAR *)NetIF_GetTxDataAlignPtr((NET_IF_NBR) p_conn->IF_Nbr, 523 | (void *)&IPerf_Buf[0], 524 | (NET_ERR *)&err); 525 | if (err != NET_IF_ERR_NONE) { 526 | p_data_buf = &IPerf_Buf[0]; 527 | } 528 | 529 | #else 530 | p_data_buf = &IPerf_Buf[0]; 531 | #endif 532 | 533 | NetSock_CfgTimeoutRxQ_Set(p_conn->SockID, IPERF_CFG_SERVER_TCP_RX_MAX_TIMEOUT_MS, &err); 534 | 535 | #if ((IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) || \ 536 | (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED)) 537 | p_stats = &p_test->Stats; 538 | #endif 539 | 540 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 541 | rx_started = DEF_NO; 542 | #endif 543 | 544 | rx_done = DEF_NO; 545 | 546 | IPERF_TRACE_INFO(("TCP Socket Received start... \n\r")); 547 | while (rx_done == DEF_NO) { /* Loop until sock is closed by the client. */ 548 | rx_done = IPerf_ServerRxPkt((IPERF_TEST *)p_test, 549 | (NET_SOCK_ID )sock_id, 550 | (CPU_CHAR *)p_data_buf, 551 | (CPU_INT16U )IPERF_SERVER_TCP_RX_MAX_RETRY, 552 | (IPERF_ERR *)p_err); 553 | 554 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 555 | cpu_usage = IPerf_OS_CPU_Usage(); 556 | p_stats->CPU_UsageAvg += cpu_usage; 557 | p_stats->CPU_CalcNbr++; 558 | if (cpu_usage > p_stats->CPU_UsageMax) { 559 | p_stats->CPU_UsageMax = cpu_usage; 560 | } 561 | #endif 562 | 563 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 564 | if (rx_started == DEF_NO) { 565 | ts_ms_prev = p_stats->TS_Start_ms; 566 | rx_bytes_prev = 0u; 567 | rx_started = DEF_YES; 568 | } 569 | IPerf_UpdateBandwidth(p_test, &ts_ms_prev, &rx_bytes_prev); 570 | #endif 571 | } 572 | 573 | p_conn->Run = DEF_NO; 574 | IPERF_TRACE_INFO(("TCP Socket Received Done\n\rClose socket accepted...")); 575 | 576 | 577 | /* -------------------- CLOSE SOCK -------------------- */ 578 | (void)NetApp_SockClose((NET_SOCK_ID) p_conn->SockID_TCP_Server, 579 | (CPU_INT32U ) 0u, 580 | (NET_ERR *)&err); 581 | switch (err) { 582 | case NET_APP_ERR_NONE: 583 | IPERF_TRACE_DBG(("Done\n\r")); 584 | break; 585 | 586 | 587 | case NET_APP_ERR_FAULT_TRANSITORY: 588 | case NET_APP_ERR_FAULT: 589 | case NET_APP_ERR_INVALID_ARG: 590 | default: 591 | if (*p_err == IPERF_ERR_NONE) { /* Don't overwrite err from IPerf_ServerRxPkt(). */ 592 | *p_err = IPERF_ERR_SERVER_SOCK_CLOSE; 593 | } 594 | IPERF_TRACE_DBG(("Error : %u.\n\r", (unsigned int)err)); 595 | break; 596 | } 597 | } 598 | 599 | 600 | /* 601 | ********************************************************************************************************* 602 | * IPerf_ServerRxWinSizeSet() 603 | * 604 | * Description : (1) Configure receive window size : 605 | * 606 | * (a) Get socket connection id 607 | * (b) Configure connection receive window size 608 | * 609 | * 610 | * Argument(s) : sock_id Windows size socket ID to change. 611 | * 612 | * win_size New windows size. 613 | * 614 | * p_err Pointer to variable that will receive the return error code from this function : 615 | * 616 | * IPERF_ERR_NONE windows size successfully set. 617 | * IPERF_ERR_SERVER_WIN_SIZE windows size NOT successfully set. 618 | * 619 | * Return(s) : none. 620 | * 621 | * Caller(s) : IPerf_ServerTCP(). 622 | * 623 | * Note(s) : none. 624 | ********************************************************************************************************* 625 | */ 626 | 627 | static void IPerf_ServerRxWinSizeSet(NET_SOCK_ID sock_id, 628 | CPU_INT16U win_size, 629 | IPERF_ERR *p_err) 630 | { 631 | NET_CONN_ID conn_id; 632 | CPU_BOOLEAN set; 633 | NET_ERR err; 634 | 635 | /* ------------------- GET CONN ID -------------------- */ 636 | conn_id = NetSock_GetConnTransportID(sock_id, &err); 637 | 638 | switch (err) { 639 | case NET_SOCK_ERR_NONE: 640 | IPERF_TRACE_DBG(("Setting window size of connection ID : %d\n\r", conn_id)); 641 | break; 642 | 643 | 644 | case NET_SOCK_ERR_INVALID_TYPE: 645 | case NET_INIT_ERR_NOT_COMPLETED: 646 | case NET_SOCK_ERR_INVALID_SOCK: 647 | case NET_SOCK_ERR_NOT_USED: 648 | case NET_CONN_ERR_INVALID_CONN: 649 | case NET_CONN_ERR_NOT_USED: 650 | case NET_ERR_FAULT_LOCK_ACQUIRE: 651 | default: 652 | IPERF_TRACE_DBG(("Setting window size fail with error : %u\n\r", (unsigned int)err)); 653 | *p_err = IPERF_ERR_SERVER_WIN_SIZE; 654 | return; 655 | } 656 | /* ------------------- SET WIN SIZE ------------------- */ 657 | #if (NET_VERSION >= 21001u) 658 | set = NetTCP_ConnCfgRxWinSize(conn_id, win_size, &err); 659 | #else 660 | set = NetTCP_ConnCfgRxWinSize(conn_id, win_size); 661 | #endif 662 | if (set == DEF_OK) { 663 | *p_err = IPERF_ERR_NONE; 664 | } else { 665 | *p_err = IPERF_ERR_SERVER_WIN_SIZE; 666 | } 667 | } 668 | 669 | 670 | /* 671 | ********************************************************************************************************* 672 | * IPerf_ServerUDP() 673 | * 674 | * Description : (1) IPerf UDP server : 675 | * 676 | * (a) Receive UDP packet 677 | * (b) Decode packet & update UDP stat 678 | * 679 | * 680 | * Argument(s) : p_test Pointer to a test. 681 | * ------ Argument validated in IPerf_Init(), 682 | * checked in IPerf_ServerStart(), 683 | * by IPerf_TestTaskHandler(). 684 | * 685 | * p_err Pointer to variable that will receive the return error code from this function 686 | * 687 | * IPERF_ERR_NONE Test successfully completed. 688 | * 689 | * ----- RETURNED BY IPerf_ServerRxPkt() : ----- 690 | * IPERF_ERR_SERVER_SOCK_RX Fatal error with rx socket. 691 | * 692 | * Return(s) : none. 693 | * 694 | * Caller(s) : IPerf_ServerStart(). 695 | * 696 | * Note(s) : none. 697 | ********************************************************************************************************* 698 | */ 699 | 700 | static void IPerf_ServerUDP (IPERF_TEST *p_test, 701 | IPERF_ERR *p_err) 702 | { 703 | IPERF_STATS *p_stats; 704 | IPERF_CONN *p_conn; 705 | CPU_CHAR *p_data_buf; 706 | IPERF_UDP_DATAGRAM *p_buf; /* Ptr to cast the buf on UDP Datagram. */ 707 | CPU_INT32U pkt_ctr; 708 | CPU_INT32S pkt_id; 709 | CPU_BOOLEAN rx_done; 710 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 711 | CPU_INT16U cpu_usage; 712 | #endif 713 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 714 | IPERF_TS_MS ts_ms_prev; 715 | CPU_INT32U rx_bytes_prev; 716 | #endif 717 | NET_ERR err; 718 | 719 | 720 | p_conn = &p_test->Conn; 721 | p_stats = &p_test->Stats; 722 | pkt_ctr = 0u; 723 | pkt_id = 0u; 724 | p_conn->Run = DEF_NO; 725 | rx_done = DEF_NO; 726 | 727 | /* ------------------- RX UDP PKTS -------------------- */ 728 | #if (IPERF_CFG_ALIGN_BUF_EN == DEF_ENABLED) 729 | p_data_buf = (CPU_CHAR *)NetIF_GetTxDataAlignPtr((NET_IF_NBR) p_conn->IF_Nbr, 730 | (void *)&IPerf_Buf[0], 731 | (NET_ERR *)&err); 732 | if (err != NET_IF_ERR_NONE) { 733 | p_data_buf = &IPerf_Buf[0]; 734 | } 735 | #else 736 | p_data_buf = &IPerf_Buf[0]; 737 | #endif 738 | 739 | NetSock_CfgTimeoutRxQ_Set(p_conn->SockID, IPERF_CFG_SERVER_UDP_RX_MAX_TIMEOUT_MS, &err); 740 | 741 | p_buf = (IPERF_UDP_DATAGRAM *)p_data_buf; 742 | 743 | IPERF_TRACE_INFO(("UDP Socket Received start\n\r")); /* Loop until end pkt rx'd or sock close from client. */ 744 | while (rx_done == DEF_NO) { 745 | rx_done = IPerf_ServerRxPkt((IPERF_TEST *)p_test, 746 | (NET_SOCK_ID )p_conn->SockID, 747 | (CPU_CHAR *)p_data_buf, 748 | (CPU_INT16U )IPERF_SERVER_UDP_RX_MAX_RETRY, 749 | (IPERF_ERR *)p_err); 750 | 751 | 752 | /*--------- DECODE RXD PKT & UPDATE UDP STATS --------- */ 753 | if (*p_err == IPERF_ERR_NONE) { 754 | pkt_ctr++; 755 | NET_UTIL_VAL_COPY_GET_NET_32(&pkt_id, &p_buf->ID); /* Copy ID from datagram to pkt ID. */ 756 | if (pkt_ctr == 1u && pkt_id >= 0) { /* First pkt rx'd. */ 757 | IPERF_TRACE_INFO(("UDP First paket received : start udp process.\n\r")); 758 | if (pkt_id > 0u) { 759 | IPERF_TRACE_DBG(("Paket ID not synchronised (first packet not received).\n\r")); 760 | p_stats->UDP_AsyncErr = DEF_YES; /*First UDP pkt from client not rx'd. */ 761 | p_stats->UDP_LostPkt++; 762 | } 763 | 764 | p_stats->TS_Start_ms = IPerf_Get_TS_ms(); 765 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 766 | ts_ms_prev = p_stats->TS_Start_ms; 767 | rx_bytes_prev = 0u; 768 | #endif 769 | p_stats->UDP_RxLastPkt = pkt_id; 770 | }else if ((pkt_ctr == 1u) && 771 | (pkt_id < 0 )) { /* Rx'd old udp fin ack ... */ 772 | pkt_ctr = 0u; /* ... discard pkt. */ 773 | p_conn->Run = DEF_NO; 774 | 775 | 776 | } else if (pkt_id < 0) { /* Rx'd end pkt. */ 777 | p_stats->TS_End_ms = IPerf_Get_TS_ms(); 778 | p_conn->Run = DEF_NO; 779 | rx_done = DEF_YES; 780 | IPerf_ServerUDP_FINACK(p_test, p_data_buf); /* Send FINACK. */ 781 | IPERF_TRACE_INFO(("UDP Socket Received done\n\r")); 782 | 783 | /* Rx'd pkt id not expected ... */ 784 | } else if ((pkt_id != (p_stats->UDP_RxLastPkt + 1)) && 785 | (pkt_ctr > 1u) ) { 786 | if (pkt_id < p_stats->UDP_RxLastPkt + 1) { /* Pkt out of order; .... */ 787 | p_stats->UDP_OutOfOrder++; 788 | } else { /* ... pkts lost. */ 789 | p_stats->UDP_LostPkt += (pkt_id - (p_stats->UDP_RxLastPkt + 1u)); 790 | } 791 | 792 | 793 | } else if ((pkt_id == p_stats->UDP_AsyncErr) && /* Rx'd dup pkt. */ 794 | (pkt_ctr > 1u) ) { 795 | p_stats->UDP_DupPkt++; 796 | } 797 | 798 | if ((pkt_ctr > 1u ) && /* Sto pkt id for next pkt decode. */ 799 | (pkt_id > p_stats->UDP_RxLastPkt)) { 800 | p_stats->UDP_RxLastPkt = pkt_id; 801 | } 802 | } 803 | 804 | #if (IPERF_CFG_CPU_USAGE_MAX_CALC_EN == DEF_ENABLED) 805 | cpu_usage = IPerf_OS_CPU_Usage(); 806 | p_stats->CPU_UsageAvg += cpu_usage; 807 | p_stats->CPU_CalcNbr++; 808 | if (cpu_usage > p_stats->CPU_UsageMax) { 809 | p_stats->CPU_UsageMax = cpu_usage; 810 | } 811 | #endif 812 | 813 | #if (IPERF_CFG_BANDWIDTH_CALC_EN == DEF_ENABLED) 814 | if (pkt_ctr > 1u) { 815 | IPerf_UpdateBandwidth(p_test, &ts_ms_prev, &rx_bytes_prev); 816 | } 817 | #endif 818 | } 819 | } 820 | 821 | 822 | /* 823 | ********************************************************************************************************* 824 | * IPerf_ServerUDP_FINACK() 825 | * 826 | * Description : (1) Server UDP FINACK send loop : 827 | * 828 | * (a) Set UDP FINACK server header 829 | * (b) Send UDP FINACK for 10 times or until received UDP FIN 830 | * (c) Try to receive UDP FIN from client 831 | * 832 | * 833 | * Argument(s) : p_test Pointer to a test. 834 | * ------ Argument validated in IPerf_Init(), 835 | * checked in IPerf_ServerUDP(), 836 | * by IPerf_TestTaskHandler(). 837 | * 838 | * p_data_buf Pointer to data to transmit. 839 | * ---------- Argument validated in IPerf_ClientUDP(). 840 | * 841 | * Return(s) : none. 842 | * 843 | * Caller(s) : IPerf_ServerUDP(). 844 | * 845 | * Note(s) : none. 846 | ********************************************************************************************************* 847 | */ 848 | 849 | static void IPerf_ServerUDP_FINACK (IPERF_TEST *p_test, 850 | CPU_CHAR *p_data_buf) 851 | { 852 | IPERF_STATS *p_stats; 853 | IPERF_CONN *p_conn; 854 | IPERF_OPT *p_opt; 855 | IPERF_UDP_DATAGRAM *p_datagram; /* Ptr to set UDP pkt datagram hdr. */ 856 | IPERF_SERVER_UDP_HDR *p_hdr; /* Ptr to set UDP pkt server hdr. */ 857 | CPU_INT08U buf_len; 858 | CPU_INT08U tx_ctr; 859 | CPU_INT16U tx_err_ctr; 860 | CPU_INT32S bytes_received; 861 | CPU_BOOLEAN done; 862 | NET_SOCK_ADDR_LEN addr_len_client; 863 | NET_ERR err; 864 | 865 | 866 | p_opt = &p_test->Opt; 867 | p_conn = &p_test->Conn; 868 | p_stats = &p_test->Stats; 869 | 870 | 871 | /* ------------------ SET SERVER HDR ------------------ */ 872 | p_datagram = (IPERF_UDP_DATAGRAM *) p_data_buf; 873 | p_hdr = (IPERF_SERVER_UDP_HDR *)p_datagram + 1u; 874 | p_hdr->Flags = NET_UTIL_HOST_TO_NET_32(IPERF_SERVER_UDP_HEADER_VERSION1); 875 | p_hdr->TotLen_Hi = 0u; 876 | p_hdr->TotLen_Lo = NET_UTIL_HOST_TO_NET_32(p_stats->Bytes & 0xFFFFFFFF); 877 | p_hdr->Stop_sec = NET_UTIL_HOST_TO_NET_32(p_stats->TS_End_ms * 1000u); 878 | p_hdr->Stop_usec = NET_UTIL_HOST_TO_NET_32(p_stats->TS_End_ms / 1000u); 879 | p_hdr->LostPkt_ctr = NET_UTIL_HOST_TO_NET_32(p_stats->UDP_LostPkt); 880 | p_hdr->OutOfOrder_ctr = NET_UTIL_HOST_TO_NET_32(p_stats->UDP_OutOfOrder); 881 | p_hdr->RxLastPkt = NET_UTIL_HOST_TO_NET_32(p_stats->UDP_RxLastPkt); 882 | p_hdr->Jitter_Hi = 0u; 883 | p_hdr->Jitter_Lo = 0u; 884 | addr_len_client = sizeof(p_conn->ClientAddrPort); 885 | buf_len = 128u; 886 | tx_ctr = 0u; 887 | tx_err_ctr = 0u; 888 | done = DEF_NO; 889 | 890 | 891 | 892 | /* ----------------- SEND UDP FINACK ------------------ */ 893 | IPERF_TRACE_DBG(("Sending FIN ACK :")); 894 | while (done == DEF_NO) { 895 | (void)NetApp_SockTx((NET_SOCK_ID ) p_conn->SockID, 896 | (void *) p_data_buf, 897 | (CPU_INT16U ) buf_len, 898 | (CPU_INT16S ) NET_SOCK_FLAG_NONE, 899 | (NET_SOCK_ADDR *)&p_conn->ClientAddrPort, 900 | (NET_SOCK_ADDR_LEN) addr_len_client, 901 | (CPU_INT16U ) IPERF_SERVER_UDP_TX_MAX_RETRY, 902 | (CPU_INT32U ) 0, 903 | (CPU_INT32U ) IPERF_SERVER_UDP_TX_MAX_DLY_MS, 904 | (NET_ERR *)&err); 905 | 906 | switch (err) { 907 | case NET_APP_ERR_NONE: /* Tx successful. */ 908 | tx_ctr++; /* Inc tx cnt. */ 909 | if (tx_ctr == IPERF_SERVER_UDP_TX_FINACK_COUNT) { 910 | done = DEF_YES; 911 | } 912 | IPERF_TRACE_DBG((".")); 913 | break; 914 | 915 | 916 | case NET_APP_ERR_CONN_CLOSED: 917 | case NET_APP_ERR_FAULT: 918 | case NET_APP_ERR_INVALID_ARG: 919 | case NET_APP_ERR_INVALID_OP: 920 | tx_ctr = IPERF_SERVER_UDP_TX_FINACK_COUNT; 921 | break; 922 | 923 | 924 | case NET_ERR_TX: 925 | default: 926 | IPERF_TRACE_INFO(("Tx error : %u\n\r", (unsigned int)err)); 927 | tx_err_ctr++; 928 | if (tx_err_ctr > IPERF_SERVER_UDP_TX_FINACK_ERR_MAX) { 929 | p_stats->UDP_EndErr = DEF_YES; 930 | IPERF_TRACE_INFO(("Tx errors exceed maximum, %u FIN ACK was send\n\r", (unsigned int)tx_ctr)); 931 | done = DEF_YES; 932 | } 933 | break; 934 | } 935 | 936 | 937 | /* ------------- TRY TO RX CLIENT UDP FIN ------------- */ 938 | bytes_received = NetApp_SockRx((NET_SOCK_ID ) p_conn->SockID, 939 | (void *) p_data_buf, 940 | (CPU_INT16U ) p_opt->BufLen, 941 | (CPU_INT16U ) 0u, 942 | (CPU_INT16S ) NET_SOCK_FLAG_NONE, 943 | (NET_SOCK_ADDR *)&p_conn->ClientAddrPort, 944 | (NET_SOCK_ADDR_LEN *)&addr_len_client, 945 | (CPU_INT16U ) 0u, 946 | (CPU_INT32U ) IPERF_RX_UDP_FINACK_MAX_TIMEOUT_MS, 947 | (CPU_INT32U ) 0u, 948 | (NET_ERR *)&err); 949 | 950 | if ((err == NET_SOCK_ERR_NONE) && 951 | (bytes_received > 0u )) { 952 | bytes_received = NetApp_SockRx((NET_SOCK_ID ) p_conn->SockID, 953 | (void *) p_data_buf, 954 | (CPU_INT16U ) p_opt->BufLen, 955 | (CPU_INT16U ) 0u, 956 | (CPU_INT16S ) NET_SOCK_FLAG_NONE, 957 | (NET_SOCK_ADDR *)&p_conn->ClientAddrPort, 958 | (NET_SOCK_ADDR_LEN *)&addr_len_client, 959 | (CPU_INT16U ) 0u, 960 | (CPU_INT32U ) IPERF_RX_UDP_FINACK_MAX_TIMEOUT_MS, 961 | (CPU_INT32U ) 0u, 962 | (NET_ERR *)&err); 963 | if (bytes_received <= 0u) { 964 | done = DEF_YES; /* Conn closed or sock err. */ 965 | } 966 | } else if ((err == NET_ERR_RX) && 967 | (bytes_received == 0u )) { 968 | done = DEF_YES; 969 | } 970 | 971 | } 972 | IPERF_TRACE_DBG(("End UDP receive process\n\r\n\r")); 973 | } 974 | 975 | 976 | 977 | /* 978 | ********************************************************************************************************* 979 | * IPerf_ServerRxPkt() 980 | * 981 | * Description : Receive packet through a socket. 982 | * 983 | * Argument(s) : p_test Pointer to a test. 984 | * ------ Argument validated in IPerf_Init(); 985 | * checked in IPerf_ServerTCP(); 986 | * IPerf_ServerUDP(). 987 | * by IPerf_TestTaskHandler(). 988 | * 989 | * sock_id Socket descriptor/handle identifier of socket to receive data. 990 | * 991 | * p_data_buf Pointer to data to transmit. 992 | * ---------- Argument validated in IPerf_ServerTCP(), 993 | * IPerf_ServerUDP. 994 | * 995 | * retry_max Maximum number of consecutive socket receive retries. 996 | * 997 | * p_err Pointer to variable that will receive the return error code from this function 998 | * 999 | * IPERF_ERR_NONE NO error with receive socket. 1000 | * IPERF_ERR_SERVER_SOCK_RX fatal error with receive socket. 1001 | * 1002 | * 1003 | * 1004 | * Return(s) : DEF_YES Socket ready to receive paket, 1005 | * DEF_NO Socket NOT ready to receive more paket. 1006 | * 1007 | * Caller(s) : IPerf_ServerTCP(), 1008 | * IPerf_ServerUDP(). 1009 | * 1010 | * Note(s) : none. 1011 | ********************************************************************************************************* 1012 | */ 1013 | static CPU_BOOLEAN IPerf_ServerRxPkt (IPERF_TEST *p_test, 1014 | NET_SOCK_ID sock_id, 1015 | CPU_CHAR *p_data_buf, 1016 | CPU_INT16U retry_max, 1017 | IPERF_ERR *p_err) 1018 | { 1019 | IPERF_OPT *p_opt; 1020 | IPERF_CONN *p_conn; 1021 | IPERF_STATS *p_stats; 1022 | NET_SOCK_ADDR_LEN addr_len_client; 1023 | CPU_INT16S rx_len; 1024 | CPU_INT16U rx_buf_len; 1025 | CPU_BOOLEAN rx_done; 1026 | CPU_BOOLEAN rx_server_done; 1027 | NET_ERR err; 1028 | 1029 | 1030 | p_opt = &p_test->Opt; 1031 | p_conn = &p_test->Conn; 1032 | p_stats = &p_test->Stats; 1033 | rx_buf_len = p_opt->BufLen; 1034 | rx_done = DEF_NO; 1035 | rx_server_done = DEF_NO; 1036 | *p_err = IPERF_ERR_NONE; 1037 | rx_buf_len = p_opt->BufLen; 1038 | 1039 | while ((rx_done == DEF_NO) && 1040 | (rx_server_done == DEF_NO)) { 1041 | /* --------------- RX PKT THROUGH SOCK ---------------- */ 1042 | p_stats->NbrCalls++; 1043 | addr_len_client = sizeof(p_conn->ClientAddrPort); 1044 | rx_len = NetApp_SockRx((NET_SOCK_ID ) sock_id, 1045 | (void *) p_data_buf, 1046 | (CPU_INT16U ) rx_buf_len, 1047 | (CPU_INT16U ) 0u, 1048 | (CPU_INT16S ) NET_SOCK_FLAG_NONE, 1049 | (NET_SOCK_ADDR *)&p_conn->ClientAddrPort, 1050 | (NET_SOCK_ADDR_LEN *)&addr_len_client, 1051 | (CPU_INT16U ) retry_max, 1052 | (CPU_INT32U ) 0, 1053 | (CPU_INT32U ) 0, 1054 | (NET_ERR *)&err); 1055 | p_stats->Bytes += rx_len; 1056 | switch (err) { 1057 | case NET_APP_ERR_NONE: 1058 | case NET_APP_ERR_DATA_BUF_OVF: 1059 | rx_done = DEF_YES; 1060 | if (p_conn->Run == DEF_NO) { 1061 | IPerf_TestClrStats(p_stats); 1062 | p_stats->TS_Start_ms = IPerf_Get_TS_ms(); 1063 | p_stats->TS_End_ms = 0u; 1064 | p_conn->Run = DEF_YES; 1065 | } 1066 | break; 1067 | 1068 | 1069 | case NET_ERR_RX: /* Transitory rx err(s), ... */ 1070 | p_stats->TransitoryErrCnts++; 1071 | break; 1072 | 1073 | 1074 | case NET_APP_ERR_CONN_CLOSED: /* Conn closed by peer. */ 1075 | p_stats->TS_End_ms = IPerf_Get_TS_ms(); 1076 | rx_server_done = DEF_YES; 1077 | break; 1078 | 1079 | 1080 | case NET_APP_ERR_FAULT: 1081 | case NET_APP_ERR_INVALID_ARG: 1082 | case NET_APP_ERR_INVALID_OP: 1083 | default: 1084 | p_stats->Errs++; 1085 | rx_server_done = DEF_YES; 1086 | *p_err = IPERF_ERR_SERVER_SOCK_RX; /* Rtn fatal err(s). */ 1087 | break; 1088 | } 1089 | } 1090 | 1091 | return (rx_server_done); 1092 | } 1093 | 1094 | /* 1095 | ********************************************************************************************************* 1096 | * MODULE END 1097 | * 1098 | * Note(s) : (1) See 'MODULE'. 1099 | ********************************************************************************************************* 1100 | */ 1101 | 1102 | #endif /* End of IPerf server module include (see Note #1). */ 1103 | 1104 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # uC/IPerf 2 | 3 | µC/IPerf is Micrium's IPerf module. It features: 4 | 5 | * Delivered with complete 100% ANSI C source code and in-depth documentation. 6 | * Easy configuration 7 | * Simple API 8 | 9 | µC/IPerf is a component of µC/TCP-IP. 10 | 11 | ## For the complete documentation, visit https://doc.micrium.com/display/ucos/ --------------------------------------------------------------------------------