RPC: Add command line option support for RPC host

The RPC host program needs to be rebuilt whenever the transportation is changed.
This patch adds support for command-line options for RPC transportation so that the host app does not have to rebuild.
Follow README.rst on how to use it.

Signed-off-by: Jason Guo <jason.guo@arm.com>
Change-Id: I0acf3570cb0d0808caa4263b16749feaf7267865
diff --git a/erpc/host_example/CMakeLists.txt b/erpc/host_example/CMakeLists.txt
index 626e08a..d718be0 100644
--- a/erpc/host_example/CMakeLists.txt
+++ b/erpc/host_example/CMakeLists.txt
@@ -15,10 +15,6 @@
 
 add_subdirectory(../client client)
 
-if (NOT DEFINED ERPC_TRANSPORT)
-    message(FATAL_ERROR "Please select ERPC_TRANSPORT, currently only UART and TCP are supported!")
-endif()
-
 if (ERPC_TRANSPORT STREQUAL "UART")
     if (NOT DEFINED PORT_NAME)
         message(FATAL_ERROR "Please provide PORT_NAME!")
@@ -27,7 +23,7 @@
     if((NOT DEFINED ERPC_HOST) OR (NOT DEFINED ERPC_PORT))
         message(FATAL_ERROR "Please provide ERPC_HOST and ERPC_PORT!")
     endif()
-else()
+elseif (DEFINED ERPC_TRANSPORT)
     message(FATAL_ERROR "Please provided supported transportation type (UART and TCP)!")
 endif()
 
@@ -35,10 +31,10 @@
     PRIVATE
         main.c
         ${ERPC_REPO_PATH}/erpc_c/port/erpc_threading_pthreads.cpp
-        $<$<STREQUAL:${ERPC_TRANSPORT},UART>:${ERPC_REPO_PATH}/erpc_c/setup/erpc_setup_serial.cpp>
-        $<$<STREQUAL:${ERPC_TRANSPORT},UART>:${ERPC_REPO_PATH}/erpc_c/transports/erpc_serial_transport.cpp>
-        $<$<STREQUAL:${ERPC_TRANSPORT},TCP>:${ERPC_REPO_PATH}/erpc_c/setup/erpc_setup_tcp.cpp>
-        $<$<STREQUAL:${ERPC_TRANSPORT},TCP>:${ERPC_REPO_PATH}/erpc_c/transports/erpc_tcp_transport.cpp>
+        ${ERPC_REPO_PATH}/erpc_c/setup/erpc_setup_serial.cpp
+        ${ERPC_REPO_PATH}/erpc_c/transports/erpc_serial_transport.cpp
+        ${ERPC_REPO_PATH}/erpc_c/setup/erpc_setup_tcp.cpp
+        ${ERPC_REPO_PATH}/erpc_c/transports/erpc_tcp_transport.cpp
         ${TFM_INSTALL_PATH}/interface/src/tfm_crypto_api.c
 )
 
diff --git a/erpc/host_example/README.rst b/erpc/host_example/README.rst
index e516e2b..3c59119 100644
--- a/erpc/host_example/README.rst
+++ b/erpc/host_example/README.rst
@@ -35,6 +35,10 @@
     -DERPC_TRANSPORT=UART -DPORT_NAME="/dev/ttyACM0"
     cmake --build  build/
 
+.. Note::
+    The ``ERPC_TRANSPORT`` and ``PORT_NAME`` can be omitted and setting the transportation info
+    in command line is also supported. Follow `Run instructions`_ on how to use the command line.
+
 Run instructions
 ----------------
 
@@ -46,6 +50,11 @@
       cd <TF-M tests base folder>/erpc/host_example
       ./build/erpc_main
 
+  .. Note::
+      If ``ERPC_TRANSPORT`` and ``PORT_NAME`` are not set, then they should be set as arguments of
+      ``erpc_main``. Execute the following command to run eRPC program:
+      ./build/erpc_main --UART /dev/ttyACM0
+
 Example: TCP Transportation on AN521 FVP
 ========================================
 
@@ -69,6 +78,11 @@
     -DERPC_TRANSPORT=TCP -DERPC_HOST="0.0.0.0" -DERPC_PORT=5001
     cmake --build  build/
 
+.. Note::
+    The ``ERPC_TRANSPORT``, ``ERPC_HOST`` and ``ERPC_PORT`` can be omitted and setting the
+    transportation info in command line is also supported. Follow `Run instructions`_ on
+    how to use the command line.
+
 Run instructions
 ----------------
 
@@ -104,6 +118,11 @@
     cd <TF-M tests base folder>/erpc/host_example
     ./build/erpc_main
 
+.. Note::
+      If ``ERPC_TRANSPORT``, ``ERPC_HOST`` and ``ERPC_PORT`` are not set, then they should be set as
+      arguments of ``erpc_main``. Execute the following command to run eRPC program:
+      ./build/erpc_main --TCP 0.0.0.0 5001
+
 --------------
 
 *Copyright (c) 2023, Arm Limited. All rights reserved.*
diff --git a/erpc/host_example/main.c b/erpc/host_example/main.c
index ddf2665..1545525 100644
--- a/erpc/host_example/main.c
+++ b/erpc/host_example/main.c
@@ -15,6 +15,13 @@
 #include "psa/client.h"
 #include "psa/crypto.h"
 
+#if (!defined(ERPC_TRANSPORT_UART)) && (!defined(ERPC_TRANSPORT_TCP))
+#include <stdlib.h>
+#include <getopt.h>
+#define ARGC_UART 3
+#define ARGC_TCP 4
+#endif
+
 static void test_call(void)
 {
     psa_status_t status;
@@ -37,12 +44,61 @@
 {
     erpc_transport_t transport;
 
+#if (!defined(ERPC_TRANSPORT_UART)) && (!defined(ERPC_TRANSPORT_TCP))
+    int erpc_uart_flag = 0, erpc_tcp_flag = 0;
+    char *uart_dev = NULL, *tcp_host = NULL, *tcp_port = NULL;
+    struct option erpc_transport_options[] =
+    {
+        {"UART", no_argument, &erpc_uart_flag, 1},
+        {"TCP", no_argument, &erpc_tcp_flag, 1},
+        {0, 0, 0, 0}
+    };
+#endif
+
 #ifdef ERPC_TRANSPORT_UART
     transport = erpc_transport_serial_init(PORT_NAME, 115200);
 #elif defined(ERPC_TRANSPORT_TCP)
     transport = erpc_transport_tcp_init(ERPC_HOST, ERPC_PORT, false);
 #else
-#error "No valid transportation layer selected."
+    /* Check if argc is correct */
+    if (argc != ARGC_UART && argc != ARGC_TCP) {
+        printf("Incorrect argument numbers.\r\n");
+        printf("Please input --UART PORT or --TCP HOST PORT\r\n");
+        return 1;
+    }
+
+    /* Loop check to set _flag and parse arguments */
+    while (getopt_long(argc, argv, "", erpc_transport_options, NULL) != -1);
+    if (!erpc_uart_flag && !erpc_tcp_flag) {
+        printf("No valid transportation layer selected.\r\n");
+        return 1;
+    } else if(erpc_uart_flag && erpc_tcp_flag) {
+        printf("UART and TCP cannot be set at the same time.\r\n");
+        return 1;
+    } else if (erpc_uart_flag) {
+        if (argc - optind != 1) {
+            printf("Incorrect argument numbers for --UART.\r\n");
+            return 1;
+        }
+        uart_dev = argv[optind];
+    } else if (erpc_tcp_flag) {
+        if (argc - optind != 2) {
+            printf("Incorrect argument numbers for --TCP.\r\n");
+        return 1;
+        }
+        tcp_host = argv[optind];
+        tcp_port = argv[optind + 1];
+    }
+
+    /* eRPC transport initialization */
+    if (erpc_uart_flag) {
+        printf("UART device is setting to %s\r\n",uart_dev);
+        transport = erpc_transport_serial_init(uart_dev, 115200);
+    } else if (erpc_tcp_flag) {
+        printf("TCP host is setting to %s\t",tcp_host);
+        printf("TCP port is setting to %s\r\n",tcp_port);
+        transport = erpc_transport_tcp_init(tcp_host, atoi(tcp_port), false);
+    }
 #endif
 
     if (!transport) {