code-shuffle to allow multiple connections (one at a time though)
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 8 Apr 2021 14:00:40 +0000 (15:00 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 8 Apr 2021 14:00:40 +0000 (15:00 +0100)
small_jtag_test/main.cpp

index e153d76436ccc15d422bb8fa394ac93934ead763..f277deecf4c95fe790b6c2b571adbcbe6d343a17 100644 (file)
@@ -18,6 +18,64 @@ using namespace std;
 
 extern "C" {
 
+/* nothing sophisticated: set up a listening socket
+ */
+int setup_socket()
+{
+       int listenfd = 0;
+       struct sockaddr_in serv_addr;
+
+       listenfd = socket(AF_INET, SOCK_STREAM, 0);
+       memset(&serv_addr, '0', sizeof(serv_addr));
+
+       serv_addr.sin_family = AF_INET;
+       serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+       serv_addr.sin_port = htons(5000);
+
+       bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
+       listen(listenfd, 1);
+
+    return listenfd;
+}
+
+/* sees if there is an incoming connection (non-blocking).  if so,
+   accept it and return it
+ */
+int get_connection(int listenfd)
+{
+       int connfd = 0;
+    int flag = 1;
+    int status;
+    fd_set active_fd_set;
+
+    struct   timeval tv;
+
+    tv.tv_sec = 0;
+    tv.tv_usec = 1;
+
+    /* Initialize the set of active sockets. */
+    FD_ZERO (&active_fd_set);
+    FD_SET (listenfd, &active_fd_set);
+
+    /* Block until input arrives on one or more active sockets. */
+    status = select (FD_SETSIZE, &active_fd_set, NULL, NULL, &tv);
+    switch (status)
+    {
+        case -1:
+            printf("Error listening on socket\n");
+            exit(status); // error
+            return -1;
+        case 0:
+            return -1; // timeout (nothing read)
+        default:
+            // return accepted socket
+            connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
+            setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag,
+                       sizeof(int));
+            return connfd;
+    }
+}
+
 /* reads from a socket if it is ready (a single byte) and returns 1 if success
  */
 int read_handler(int fdread, char *buffer)
@@ -25,9 +83,9 @@ int read_handler(int fdread, char *buffer)
     ssize_t read_len;
     fd_set read_fds;
     FD_ZERO(&read_fds);
-    struct   timeval tv;
     FD_SET(fdread, &read_fds);
     int status;
+    struct   timeval tv;
 
     tv.tv_sec = 0;
     tv.tv_usec = 1;
@@ -46,32 +104,6 @@ int read_handler(int fdread, char *buffer)
     }
 }
 
-/* nothing sophisticated: wait for an incoming connection
- */
-int get_connection()
-{
-       int listenfd = 0, connfd = 0;
-    int flag = 1;
-       struct sockaddr_in serv_addr;
-
-       listenfd = socket(AF_INET, SOCK_STREAM, 0);
-       memset(&serv_addr, '0', sizeof(serv_addr));
-
-       serv_addr.sin_family = AF_INET;
-       serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-       serv_addr.sin_port = htons(5000);
-
-       bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
-
-       listen(listenfd, 1);
-
-    connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
-    close(listenfd);
-
-    setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
-    return connfd;
-}
-
 } // extern "C"
 
 /* main function which polls the socket and talks openocd jtagremote protocol.
@@ -79,11 +111,11 @@ int get_connection()
    indicates that receiver wants to know the status of TDO.
    "Q" means "quit socket".
 */
-void read_openocd_jtagremote(cxxrtl_design::p_add &top, int sock)
+int read_openocd_jtagremote(cxxrtl_design::p_add &top, int sock)
 {
     char c;
     if (read_handler(sock, &c) != 1) {
-        return;
+        return sock;
     }
     printf ("read %c\n", c);
     if ((c >= '0') && (c <= '7'))
@@ -98,20 +130,24 @@ void read_openocd_jtagremote(cxxrtl_design::p_add &top, int sock)
         if(-1 == write(sock, &val, 1))
         {
             printf("Error writing on socket\n");
-            exit(-1);
+            close(sock);
+            sock = -1;
         }
     }
     if (c == 'Q') {
         printf("disconnect request\n");
-        exit(-1);
+            close(sock);
+        sock = -1;
     }
+    return sock;
 }
 
 int main()
 {
     cxxrtl_design::p_add top;
 
-    int sock = get_connection();
+    int listenfd = setup_socket();
+    int sock = -1;
 
     top.step();
     while (true) {
@@ -121,8 +157,12 @@ int main()
         top.p_clk.set<bool>(true);
         top.step();
 
-        /* read and process incoming jtag */
-        read_openocd_jtagremote(top, sock);
+        // if no current connection see if there is one
+        if (sock == -1) {
+            sock = get_connection(listenfd);
+        }
+        /* read and process incoming jtag. sock set to -1 if disconnected */
+        sock = read_openocd_jtagremote(top, sock);
 
         // quick check that the output is correct (it's an adder: go figure)
         /*