]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - tools/src/tools/ecostest/common/ser_filter.cpp
Initial revision
[karo-tx-redboot.git] / tools / src / tools / ecostest / common / ser_filter.cpp
diff --git a/tools/src/tools/ecostest/common/ser_filter.cpp b/tools/src/tools/ecostest/common/ser_filter.cpp
new file mode 100644 (file)
index 0000000..eb61d31
--- /dev/null
@@ -0,0 +1,318 @@
+//####COPYRIGHTBEGIN####
+//                                                                          
+// ----------------------------------------------------------------------------
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
+//
+// This program is part of the eCos host tools.
+//
+// This program is free software; you can redistribute it and/or modify it 
+// under the terms of the GNU General Public License as published by the Free 
+// Software Foundation; either version 2 of the License, or (at your option) 
+// any later version.
+// 
+// This program is distributed in the hope that it will be useful, but WITHOUT 
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+// more details.
+// 
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+// ----------------------------------------------------------------------------
+//                                                                          
+//####COPYRIGHTEND####
+//=================================================================
+//
+//        ser_filter.cxx
+//
+//        Serial test filter
+//
+//=================================================================
+//=================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     jskov
+// Contributors:  jskov
+// Date:          1999-03-01
+// Description:   This program acts as a filter between GDB and the test
+//                running on the target, allowing testing of the serial
+//                driver without confusing GDB.
+// Usage:         Run the program with one argument, the serial port
+//                on with the target is connected.
+//                Run serial test in GDB, connecting to the target with
+//                'target remote localhost:5678'.
+//
+// To Do:
+//  o Add timeout setup and handling for recovery, can rely on testing
+//    agent to control global timeout.
+//  o Saving chunks that caused transfer failure?
+//     - In SEND with echo, do CRC on 32-byte sub-packets
+//  o Additional To Do items under each sub-protocol function.
+//  o Option to get all serial IO written (in hex, > and < prepends 
+//    input/output lines) to a file.
+//  o Clean up the mess in this file....
+//  o Make main() listen on two ports - use one for ser filter, the other for
+//    null filter connections.
+//  o Maybe use environment variable to find X10 reset command.
+//####DESCRIPTIONEND####
+
+#include "eCosTestSerialFilter.h"
+#include "eCosTestDownloadFilter.h"
+#include "eCosTestMonitorFilter.h"
+#include "eCosTestUtils.h"
+#include "eCosThreadUtils.h"
+#include "eCosTrace.h"
+
+bool opt_ser_debug = false;
+bool opt_null_filter = false;
+bool opt_console_output = false;
+bool opt_X10_reset = false;
+bool opt_filter_trace = false;
+char opt_X10_port[2];
+bool opt_monitor = false;
+
+void
+no_gdb(const char* pszPort, int nBaud, 
+       CeCosSocket::FilterFunc *pSerialToSocketFilterFunc,
+       void *pParam, bool *pbStop)
+{
+  fprintf(stderr, "no_gdb, listening on %s\n",pszPort);
+  
+  CeCosSocket dummy_socket;
+  CeCosSerial serial;
+  serial.SetBlockingReads(false);
+  bool rc=false;
+  
+  // Open serial device.
+  if (!serial.Open(pszPort,nBaud)){
+    ERROR("Couldn't open port %s\n",pszPort);
+  } else {
+    // Flush the serial buffer.
+    serial.Flush();
+    
+    serial.ClearError();
+    enum {BUFSIZE=8192};
+    void *pBuf=malloc(BUFSIZE);
+    rc=true;
+    while(rc && (0==pbStop || !(*pbStop))){
+      unsigned int nRead=0;
+      
+      for(;;) {
+        if(serial.Read(pBuf,BUFSIZE,nRead)){
+          if(nRead>0){
+            break;
+          }
+          CeCosThreadUtils::Sleep(1);
+        } else {
+          fprintf(stderr, "Serial read failed (%d)\n", errno);
+        }
+      }
+      
+      if(pSerialToSocketFilterFunc){
+        rc=pSerialToSocketFilterFunc(pBuf,nRead,serial,dummy_socket,
+          pParam);
+      }
+    }
+    free(pBuf);
+  }
+}
+
+int
+main(int argc, char** argv)
+{
+  int nSock = 0;
+  int baud_rate, nTcpPort;
+  
+  bool opt_no_gdb = false;
+  char* ser_port;
+  int i=1;
+  if(!CeCosTestUtils::CommandLine(argc, argv, false)){
+    goto Usage;
+  }
+  
+  while(i<argc){
+    if(argv[i][0]=='-'){
+      switch(argv[i][1]){
+      case 't':
+        // redundant - -v does this
+        CeCosTrace ::EnableTracing(CeCosTrace::TRACE_LEVEL_TRACE);
+        break;
+      case 'f':
+        opt_filter_trace = true;
+        break;
+      case 'S':
+        opt_ser_debug = true;
+        break;
+      case 'm':
+        opt_monitor = true;
+        break;
+      case 'n':
+        opt_no_gdb = true;
+        // fall through! Output on console when no GDB.
+      case 'c':
+        opt_console_output = true;
+        break;
+      case '0':
+        opt_null_filter = true;
+        break;
+      case 'X':
+        // X-10 port to reset when connection drops
+        opt_X10_reset = true;
+        opt_X10_port[0] = argv[i][2];
+        opt_X10_port[1] = argv[i][3];
+        break;
+      default:
+        fprintf(stderr,"Unrecognized switch %s\n",argv[i]);
+        goto Usage;
+        break;
+      }
+      for(int j=i;j<argc;j++){
+        argv[j]=argv[j+1];
+      }
+      argc--;
+      argv[argc]=0;
+    } else {
+      i++;
+    }
+  }
+  
+  if(!((3==argc && opt_no_gdb) || (4==argc && !opt_no_gdb)))
+  {
+    goto Usage;
+  }
+  
+  if (opt_no_gdb) {
+    ser_port = argv[1];
+    baud_rate=atoi(argv[2]);
+  } else {
+    nTcpPort=atoi(argv[1]);
+    if(0==nTcpPort){
+      fprintf(stderr,"Invalid port %s\n",argv[1]);
+      return main(0,argv); // Provoke usage message
+    }
+    
+    ser_port = argv[2];
+    baud_rate=atoi(argv[3]);
+    
+    nSock = CeCosSocket::Listen(nTcpPort);
+    if (-1 == nSock) {
+      fprintf(stderr, "Couldn't access socket.\n");
+      throw "listen failed";
+    }
+  }
+  
+  
+  if (opt_monitor) {
+      fprintf(stdout, "Monitor mode - will not interact with data streams...\n");
+
+      for(;;) {
+      
+          CeCosTestMonitorFilter* host_filter = 
+              new CeCosTestMonitorFilter();
+          CeCosTestMonitorFilter* target_filter = 
+              new CeCosTestMonitorFilter();
+
+          // Set filter directions
+          host_filter->SetOrigin(CeCosTestMonitorFilter::MF_HOST);
+          target_filter->SetOrigin(CeCosTestMonitorFilter::MF_TARGET);
+          
+          // Enable filters
+          host_filter->SetVerbose(true);
+          target_filter->SetVerbose(true);
+
+          // Set filter functions
+          CeCosSocket::FilterFunc *host_filter_function = 
+              &SerialMonitorFunction;
+          CeCosSocket::FilterFunc *target_filter_function = 
+              &SerialMonitorFunction;
+          
+          try {
+              CeCosSocket::ConnectSocketToSerial(nSock, ser_port, 
+                                                     baud_rate, 
+                                                     target_filter_function, 
+                                                     (void*)target_filter, 
+                                                     host_filter_function, 
+                                                     (void*)host_filter,
+                                                     NULL);
+          } 
+          catch (const char* p) {
+              fprintf(stderr, "Caught filter crash: %s\n", p);
+          }
+          
+          delete target_filter;
+          delete host_filter;
+      }
+  }
+  
+  for(;;) {
+    CeCosTestSerialFilter* serial_filter = 
+      new CeCosTestSerialFilter();
+    CeCosTestDownloadFilter* download_filter = 
+      new CeCosTestDownloadFilter();
+    
+    // Set filter configuration
+    serial_filter->SetFilterTrace(opt_filter_trace);
+    serial_filter->SetSerialDebug(opt_ser_debug);
+    serial_filter->SetConsoleOutput(opt_console_output);
+    
+    // Set download filter configuration
+    download_filter->SetFilterTrace(opt_filter_trace);
+    download_filter->SetSerialDebug(opt_ser_debug);
+    
+    // Set serial side filter
+    CeCosSocket::FilterFunc *ser_filter_function = 
+      &SerialFilterFunction;
+    if (opt_null_filter)
+      ser_filter_function = NULL;
+    
+    // Set socket side filter
+    CeCosSocket::FilterFunc *sock_filter_function =
+      &DownloadFilterFunction;
+    
+    try {
+      if (opt_no_gdb)
+        no_gdb(ser_port, baud_rate, ser_filter_function, 
+        (void*)serial_filter, NULL);
+      else
+        CeCosSocket::ConnectSocketToSerial(nSock, ser_port, 
+        baud_rate, 
+        ser_filter_function, 
+        (void*)serial_filter, 
+        sock_filter_function, 
+        (void*)download_filter,
+        NULL);
+    } 
+    catch (const char* p) {
+      fprintf(stderr, "Caught filter crash: %s\n", p);
+    }
+    
+    if (opt_X10_reset) {
+      char X10_cmd[80];
+      sprintf(X10_cmd, "/usr/unsupported/bin/x10cli x10 5000 %c %c", 
+        opt_X10_port[0], opt_X10_port[1]);
+      system(X10_cmd);
+    }
+    
+    delete serial_filter;
+    delete download_filter;
+  }
+  
+//  return 0;
+  
+Usage:
+  const char *pszMe="ser_filter";
+  fprintf(stderr,"Usage: %s [-c -S -0 -Xab] TcpIPport SerialPort BaudRate\n"
+    " or:   %s -n [-c -S -0 -Xab] SerialPort BaudRate\n"
+    " Switches:\n"
+    " -f: Enable filter output tracing.\n"
+    " -S: Output data read from serial line.\n"
+    " -c: Output data on console instead of via GDB.\n"
+    " -m: Work only as a monitor filter. Implies -c.\n"
+    " -n: No GDB.\n"
+    " -0: Use null filter.\n"
+    " -Xab: Reset X-10 Port 'a b' when TCP connection breaks\n",pszMe,pszMe);
+  CeCosTestUtils::UsageMessage();
+   
+  return 1;
+}