15b21ffb2SSunil Kumar Kori /* SPDX-License-Identifier: BSD-3-Clause 25b21ffb2SSunil Kumar Kori * Copyright(c) 2023 Marvell. 35b21ffb2SSunil Kumar Kori */ 45b21ffb2SSunil Kumar Kori 5*3f90eda5SSunil Kumar Kori #include <errno.h> 65b21ffb2SSunil Kumar Kori #include <fcntl.h> 75b21ffb2SSunil Kumar Kori #include <getopt.h> 85b21ffb2SSunil Kumar Kori #include <signal.h> 95b21ffb2SSunil Kumar Kori #include <stdio.h> 105b21ffb2SSunil Kumar Kori #include <stdlib.h> 115b21ffb2SSunil Kumar Kori #include <string.h> 125b21ffb2SSunil Kumar Kori #include <sys/select.h> 135b21ffb2SSunil Kumar Kori #include <unistd.h> 145b21ffb2SSunil Kumar Kori 15*3f90eda5SSunil Kumar Kori #include <rte_cycles.h> 165b21ffb2SSunil Kumar Kori #include <rte_eal.h> 175b21ffb2SSunil Kumar Kori #include <rte_launch.h> 185b21ffb2SSunil Kumar Kori 195b21ffb2SSunil Kumar Kori #include "module_api.h" 205b21ffb2SSunil Kumar Kori 215b21ffb2SSunil Kumar Kori volatile bool force_quit; 22*3f90eda5SSunil Kumar Kori struct conn *conn; 235b21ffb2SSunil Kumar Kori 24*3f90eda5SSunil Kumar Kori static const char usage[] = "%s EAL_ARGS -- -s SCRIPT [-h HOST] [-p PORT] " 255b21ffb2SSunil Kumar Kori "[--help]\n"; 265b21ffb2SSunil Kumar Kori 275b21ffb2SSunil Kumar Kori static struct app_params { 28*3f90eda5SSunil Kumar Kori struct conn_params conn; 295b21ffb2SSunil Kumar Kori char *script_name; 305b21ffb2SSunil Kumar Kori } app = { 31*3f90eda5SSunil Kumar Kori .conn = { 32*3f90eda5SSunil Kumar Kori .welcome = "\nWelcome!\n\n", 33*3f90eda5SSunil Kumar Kori .prompt = "graph> ", 34*3f90eda5SSunil Kumar Kori .addr = "0.0.0.0", 35*3f90eda5SSunil Kumar Kori .port = 8086, 36*3f90eda5SSunil Kumar Kori .buf_size = 1024 * 1024, 37*3f90eda5SSunil Kumar Kori .msg_in_len_max = 1024, 38*3f90eda5SSunil Kumar Kori .msg_out_len_max = 1024 * 1024, 39*3f90eda5SSunil Kumar Kori .msg_handle = cli_process, 40*3f90eda5SSunil Kumar Kori .msg_handle_arg = NULL, /* set later. */ 41*3f90eda5SSunil Kumar Kori }, 425b21ffb2SSunil Kumar Kori .script_name = NULL, 435b21ffb2SSunil Kumar Kori }; 445b21ffb2SSunil Kumar Kori 455b21ffb2SSunil Kumar Kori static void 465b21ffb2SSunil Kumar Kori signal_handler(int signum) 475b21ffb2SSunil Kumar Kori { 485b21ffb2SSunil Kumar Kori if (signum == SIGINT || signum == SIGTERM) { 495b21ffb2SSunil Kumar Kori printf("\n\nSignal %d received, preparing to exit...\n", signum); 505b21ffb2SSunil Kumar Kori force_quit = true; 515b21ffb2SSunil Kumar Kori } 525b21ffb2SSunil Kumar Kori } 535b21ffb2SSunil Kumar Kori 545b21ffb2SSunil Kumar Kori static int 555b21ffb2SSunil Kumar Kori app_args_parse(int argc, char **argv) 565b21ffb2SSunil Kumar Kori { 575b21ffb2SSunil Kumar Kori struct option lgopts[] = { 585b21ffb2SSunil Kumar Kori {"help", 0, 0, 'H'}, 595b21ffb2SSunil Kumar Kori }; 60*3f90eda5SSunil Kumar Kori int h_present, p_present, s_present, n_args, i; 615b21ffb2SSunil Kumar Kori char *app_name = argv[0]; 625b21ffb2SSunil Kumar Kori int opt, option_index; 635b21ffb2SSunil Kumar Kori 645b21ffb2SSunil Kumar Kori /* Skip EAL input args */ 655b21ffb2SSunil Kumar Kori n_args = argc; 665b21ffb2SSunil Kumar Kori for (i = 0; i < n_args; i++) 675b21ffb2SSunil Kumar Kori if (strcmp(argv[i], "--") == 0) { 685b21ffb2SSunil Kumar Kori argc -= i; 695b21ffb2SSunil Kumar Kori argv += i; 705b21ffb2SSunil Kumar Kori break; 715b21ffb2SSunil Kumar Kori } 725b21ffb2SSunil Kumar Kori 735b21ffb2SSunil Kumar Kori if (i == n_args) 745b21ffb2SSunil Kumar Kori return 0; 755b21ffb2SSunil Kumar Kori 765b21ffb2SSunil Kumar Kori /* Parse args */ 77*3f90eda5SSunil Kumar Kori h_present = 0; 78*3f90eda5SSunil Kumar Kori p_present = 0; 795b21ffb2SSunil Kumar Kori s_present = 0; 805b21ffb2SSunil Kumar Kori 81*3f90eda5SSunil Kumar Kori while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index)) != EOF) { 825b21ffb2SSunil Kumar Kori switch (opt) { 83*3f90eda5SSunil Kumar Kori case 'h': 84*3f90eda5SSunil Kumar Kori if (h_present) { 85*3f90eda5SSunil Kumar Kori printf("Error: Multiple -h arguments\n"); 86*3f90eda5SSunil Kumar Kori return -1; 87*3f90eda5SSunil Kumar Kori } 88*3f90eda5SSunil Kumar Kori h_present = 1; 89*3f90eda5SSunil Kumar Kori 90*3f90eda5SSunil Kumar Kori if (!strlen(optarg)) { 91*3f90eda5SSunil Kumar Kori printf("Error: Argument for -h not provided\n"); 92*3f90eda5SSunil Kumar Kori return -1; 93*3f90eda5SSunil Kumar Kori } 94*3f90eda5SSunil Kumar Kori 95*3f90eda5SSunil Kumar Kori app.conn.addr = strdup(optarg); 96*3f90eda5SSunil Kumar Kori if (app.conn.addr == NULL) { 97*3f90eda5SSunil Kumar Kori printf("Error: Not enough memory\n"); 98*3f90eda5SSunil Kumar Kori return -1; 99*3f90eda5SSunil Kumar Kori } 100*3f90eda5SSunil Kumar Kori break; 101*3f90eda5SSunil Kumar Kori 102*3f90eda5SSunil Kumar Kori case 'p': 103*3f90eda5SSunil Kumar Kori if (p_present) { 104*3f90eda5SSunil Kumar Kori printf("Error: Multiple -p arguments\n"); 105*3f90eda5SSunil Kumar Kori return -1; 106*3f90eda5SSunil Kumar Kori } 107*3f90eda5SSunil Kumar Kori p_present = 1; 108*3f90eda5SSunil Kumar Kori 109*3f90eda5SSunil Kumar Kori if (!strlen(optarg)) { 110*3f90eda5SSunil Kumar Kori printf("Error: Argument for -p not provided\n"); 111*3f90eda5SSunil Kumar Kori return -1; 112*3f90eda5SSunil Kumar Kori } 113*3f90eda5SSunil Kumar Kori 114*3f90eda5SSunil Kumar Kori app.conn.port = (uint16_t)strtoul(optarg, NULL, 10); 115*3f90eda5SSunil Kumar Kori break; 116*3f90eda5SSunil Kumar Kori 1175b21ffb2SSunil Kumar Kori case 's': 1185b21ffb2SSunil Kumar Kori if (s_present) { 1195b21ffb2SSunil Kumar Kori printf("Error: Multiple -s arguments\n"); 1205b21ffb2SSunil Kumar Kori return -1; 1215b21ffb2SSunil Kumar Kori } 1225b21ffb2SSunil Kumar Kori s_present = 1; 1235b21ffb2SSunil Kumar Kori 1245b21ffb2SSunil Kumar Kori if (!strlen(optarg)) { 1255b21ffb2SSunil Kumar Kori printf("Error: Argument for -s not provided\n"); 1265b21ffb2SSunil Kumar Kori return -1; 1275b21ffb2SSunil Kumar Kori } 1285b21ffb2SSunil Kumar Kori 1295b21ffb2SSunil Kumar Kori app.script_name = strdup(optarg); 1305b21ffb2SSunil Kumar Kori if (app.script_name == NULL) { 1315b21ffb2SSunil Kumar Kori printf("Error: Not enough memory\n"); 1325b21ffb2SSunil Kumar Kori return -1; 1335b21ffb2SSunil Kumar Kori } 1345b21ffb2SSunil Kumar Kori break; 1355b21ffb2SSunil Kumar Kori 1365b21ffb2SSunil Kumar Kori case 'H': 1375b21ffb2SSunil Kumar Kori default: 1385b21ffb2SSunil Kumar Kori printf(usage, app_name); 1395b21ffb2SSunil Kumar Kori return -1; 1405b21ffb2SSunil Kumar Kori } 1415b21ffb2SSunil Kumar Kori } 1425b21ffb2SSunil Kumar Kori optind = 1; /* reset getopt lib */ 1435b21ffb2SSunil Kumar Kori 1445b21ffb2SSunil Kumar Kori return 0; 1455b21ffb2SSunil Kumar Kori } 1465b21ffb2SSunil Kumar Kori 147*3f90eda5SSunil Kumar Kori bool 148*3f90eda5SSunil Kumar Kori app_graph_exit(void) 149*3f90eda5SSunil Kumar Kori { 150*3f90eda5SSunil Kumar Kori struct timeval tv; 151*3f90eda5SSunil Kumar Kori fd_set fds; 152*3f90eda5SSunil Kumar Kori int ret; 153*3f90eda5SSunil Kumar Kori char c; 154*3f90eda5SSunil Kumar Kori 155*3f90eda5SSunil Kumar Kori FD_ZERO(&fds); 156*3f90eda5SSunil Kumar Kori FD_SET(0, &fds); 157*3f90eda5SSunil Kumar Kori tv.tv_sec = 0; 158*3f90eda5SSunil Kumar Kori tv.tv_usec = 100; 159*3f90eda5SSunil Kumar Kori ret = select(1, &fds, NULL, NULL, &tv); 160*3f90eda5SSunil Kumar Kori if ((ret < 0 && errno == EINTR) || (ret == 1 && read(0, &c, 1) > 0)) 161*3f90eda5SSunil Kumar Kori return true; 162*3f90eda5SSunil Kumar Kori else 163*3f90eda5SSunil Kumar Kori return false; 164*3f90eda5SSunil Kumar Kori 165*3f90eda5SSunil Kumar Kori } 166*3f90eda5SSunil Kumar Kori 1675b21ffb2SSunil Kumar Kori int 1685b21ffb2SSunil Kumar Kori main(int argc, char **argv) 1695b21ffb2SSunil Kumar Kori { 1705b21ffb2SSunil Kumar Kori int rc; 1715b21ffb2SSunil Kumar Kori 1725b21ffb2SSunil Kumar Kori /* Parse application arguments */ 1735b21ffb2SSunil Kumar Kori rc = app_args_parse(argc, argv); 1745b21ffb2SSunil Kumar Kori if (rc < 0) 1755b21ffb2SSunil Kumar Kori return rc; 1765b21ffb2SSunil Kumar Kori 1775b21ffb2SSunil Kumar Kori /* EAL */ 1785b21ffb2SSunil Kumar Kori rc = rte_eal_init(argc, argv); 1795b21ffb2SSunil Kumar Kori if (rc < 0) { 1805b21ffb2SSunil Kumar Kori printf("Error: EAL initialization failed (%d)\n", rc); 1815b21ffb2SSunil Kumar Kori return rc; 1825b21ffb2SSunil Kumar Kori }; 1835b21ffb2SSunil Kumar Kori 1845b21ffb2SSunil Kumar Kori force_quit = false; 1855b21ffb2SSunil Kumar Kori signal(SIGINT, signal_handler); 1865b21ffb2SSunil Kumar Kori signal(SIGTERM, signal_handler); 1875b21ffb2SSunil Kumar Kori 1885b21ffb2SSunil Kumar Kori cli_init(); 1895b21ffb2SSunil Kumar Kori 1905b21ffb2SSunil Kumar Kori /* Script */ 1915b21ffb2SSunil Kumar Kori if (app.script_name) { 192*3f90eda5SSunil Kumar Kori cli_script_process(app.script_name, app.conn.msg_in_len_max, 193*3f90eda5SSunil Kumar Kori app.conn.msg_out_len_max, NULL); 1945b21ffb2SSunil Kumar Kori } 1955b21ffb2SSunil Kumar Kori 196*3f90eda5SSunil Kumar Kori /* Connectivity */ 197*3f90eda5SSunil Kumar Kori app.conn.msg_handle_arg = NULL; 198*3f90eda5SSunil Kumar Kori conn = conn_init(&app.conn); 199*3f90eda5SSunil Kumar Kori if (!conn) { 200*3f90eda5SSunil Kumar Kori printf("Error: Connectivity initialization failed\n"); 201*3f90eda5SSunil Kumar Kori goto exit; 202*3f90eda5SSunil Kumar Kori }; 203*3f90eda5SSunil Kumar Kori 204*3f90eda5SSunil Kumar Kori rte_delay_ms(1); 205*3f90eda5SSunil Kumar Kori printf("Press enter to exit\n"); 206*3f90eda5SSunil Kumar Kori 207*3f90eda5SSunil Kumar Kori /* Dispatch loop */ 208*3f90eda5SSunil Kumar Kori while (!force_quit) { 209*3f90eda5SSunil Kumar Kori conn_req_poll(conn); 210*3f90eda5SSunil Kumar Kori 211*3f90eda5SSunil Kumar Kori conn_msg_poll(conn); 212*3f90eda5SSunil Kumar Kori if (app_graph_exit()) 213*3f90eda5SSunil Kumar Kori force_quit = true; 214*3f90eda5SSunil Kumar Kori } 215*3f90eda5SSunil Kumar Kori 216*3f90eda5SSunil Kumar Kori exit: 217*3f90eda5SSunil Kumar Kori conn_free(conn); 2185b21ffb2SSunil Kumar Kori cli_exit(); 2195b21ffb2SSunil Kumar Kori rte_eal_cleanup(); 2205b21ffb2SSunil Kumar Kori return 0; 2215b21ffb2SSunil Kumar Kori } 222