1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2020 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <fcntl.h> 9 #include <unistd.h> 10 #include <getopt.h> 11 12 #include <rte_launch.h> 13 #include <rte_eal.h> 14 15 #include "cli.h" 16 #include "conn.h" 17 #include "obj.h" 18 #include "thread.h" 19 20 static const char usage[] = 21 "%s EAL_ARGS -- [-h HOST] [-p PORT] [-s SCRIPT]\n"; 22 23 static struct app_params { 24 struct conn_params conn; 25 char *script_name; 26 } app = { 27 .conn = { 28 .welcome = "\nWelcome!\n\n", 29 .prompt = "pipeline> ", 30 .addr = "0.0.0.0", 31 .port = 8086, 32 .buf_size = 1024 * 1024, 33 .msg_in_len_max = 1024, 34 .msg_out_len_max = 1024 * 1024, 35 .msg_handle = cli_process, 36 .msg_handle_arg = NULL, /* set later. */ 37 }, 38 .script_name = NULL, 39 }; 40 41 static int 42 parse_args(int argc, char **argv) 43 { 44 char *app_name = argv[0]; 45 struct option lgopts[] = { 46 { NULL, 0, 0, 0 } 47 }; 48 int opt, option_index; 49 int h_present, p_present, s_present, n_args, i; 50 51 /* Skip EAL input args */ 52 n_args = argc; 53 for (i = 0; i < n_args; i++) 54 if (strcmp(argv[i], "--") == 0) { 55 argc -= i; 56 argv += i; 57 break; 58 } 59 60 if (i == n_args) 61 return 0; 62 63 /* Parse args */ 64 h_present = 0; 65 p_present = 0; 66 s_present = 0; 67 68 while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index)) 69 != EOF) 70 switch (opt) { 71 case 'h': 72 if (h_present) { 73 printf("Error: Multiple -h arguments\n"); 74 return -1; 75 } 76 h_present = 1; 77 78 if (!strlen(optarg)) { 79 printf("Error: Argument for -h not provided\n"); 80 return -1; 81 } 82 83 app.conn.addr = strdup(optarg); 84 if (app.conn.addr == NULL) { 85 printf("Error: Not enough memory\n"); 86 return -1; 87 } 88 break; 89 90 case 'p': 91 if (p_present) { 92 printf("Error: Multiple -p arguments\n"); 93 return -1; 94 } 95 p_present = 1; 96 97 if (!strlen(optarg)) { 98 printf("Error: Argument for -p not provided\n"); 99 return -1; 100 } 101 102 app.conn.port = (uint16_t) atoi(optarg); 103 break; 104 105 case 's': 106 if (s_present) { 107 printf("Error: Multiple -s arguments\n"); 108 return -1; 109 } 110 s_present = 1; 111 112 if (!strlen(optarg)) { 113 printf("Error: Argument for -s not provided\n"); 114 return -1; 115 } 116 117 app.script_name = strdup(optarg); 118 if (app.script_name == NULL) { 119 printf("Error: Not enough memory\n"); 120 return -1; 121 } 122 break; 123 124 default: 125 printf(usage, app_name); 126 return -1; 127 } 128 129 optind = 1; /* reset getopt lib */ 130 131 return 0; 132 } 133 134 int 135 main(int argc, char **argv) 136 { 137 struct conn *conn; 138 struct obj *obj; 139 int status; 140 141 /* Parse application arguments */ 142 status = parse_args(argc, argv); 143 if (status < 0) 144 return status; 145 146 /* EAL */ 147 status = rte_eal_init(argc, argv); 148 if (status < 0) { 149 printf("Error: EAL initialization failed (%d)\n", status); 150 return status; 151 }; 152 153 /* Obj */ 154 obj = obj_init(); 155 if (!obj) { 156 printf("Error: Obj initialization failed (%d)\n", status); 157 return status; 158 } 159 160 /* Thread */ 161 status = thread_init(); 162 if (status) { 163 printf("Error: Thread initialization failed (%d)\n", status); 164 return status; 165 } 166 167 rte_eal_mp_remote_launch( 168 thread_main, 169 NULL, 170 SKIP_MAIN); 171 172 /* Script */ 173 if (app.script_name) 174 cli_script_process(app.script_name, 175 app.conn.msg_in_len_max, 176 app.conn.msg_out_len_max, 177 obj); 178 179 /* Connectivity */ 180 app.conn.msg_handle_arg = obj; 181 conn = conn_init(&app.conn); 182 if (!conn) { 183 printf("Error: Connectivity initialization failed (%d)\n", 184 status); 185 return status; 186 }; 187 188 /* Dispatch loop */ 189 for ( ; ; ) { 190 conn_poll_for_conn(conn); 191 192 conn_poll_for_msg(conn); 193 } 194 195 /* clean up the EAL */ 196 rte_eal_cleanup(); 197 } 198