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