]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/tools/ecostest/common/ser_filter.cpp
Initial revision
[karo-tx-redboot.git] / tools / src / tools / ecostest / common / ser_filter.cpp
1 //####COPYRIGHTBEGIN####
2 //                                                                          
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 //
6 // This program is part of the eCos host tools.
7 //
8 // This program is free software; you can redistribute it and/or modify it 
9 // under the terms of the GNU General Public License as published by the Free 
10 // Software Foundation; either version 2 of the License, or (at your option) 
11 // any later version.
12 // 
13 // This program is distributed in the hope that it will be useful, but WITHOUT 
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
15 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
16 // more details.
17 // 
18 // You should have received a copy of the GNU General Public License along with
19 // this program; if not, write to the Free Software Foundation, Inc., 
20 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21 //
22 // ----------------------------------------------------------------------------
23 //                                                                          
24 //####COPYRIGHTEND####
25 //=================================================================
26 //
27 //        ser_filter.cxx
28 //
29 //        Serial test filter
30 //
31 //=================================================================
32 //=================================================================
33 //#####DESCRIPTIONBEGIN####
34 //
35 // Author(s):     jskov
36 // Contributors:  jskov
37 // Date:          1999-03-01
38 // Description:   This program acts as a filter between GDB and the test
39 //                running on the target, allowing testing of the serial
40 //                driver without confusing GDB.
41 // Usage:         Run the program with one argument, the serial port
42 //                on with the target is connected.
43 //                Run serial test in GDB, connecting to the target with
44 //                'target remote localhost:5678'.
45 //
46 // To Do:
47 //  o Add timeout setup and handling for recovery, can rely on testing
48 //    agent to control global timeout.
49 //  o Saving chunks that caused transfer failure?
50 //     - In SEND with echo, do CRC on 32-byte sub-packets
51 //  o Additional To Do items under each sub-protocol function.
52 //  o Option to get all serial IO written (in hex, > and < prepends 
53 //    input/output lines) to a file.
54 //  o Clean up the mess in this file....
55 //  o Make main() listen on two ports - use one for ser filter, the other for
56 //    null filter connections.
57 //  o Maybe use environment variable to find X10 reset command.
58 //####DESCRIPTIONEND####
59
60 #include "eCosTestSerialFilter.h"
61 #include "eCosTestDownloadFilter.h"
62 #include "eCosTestMonitorFilter.h"
63 #include "eCosTestUtils.h"
64 #include "eCosThreadUtils.h"
65 #include "eCosTrace.h"
66
67 bool opt_ser_debug = false;
68 bool opt_null_filter = false;
69 bool opt_console_output = false;
70 bool opt_X10_reset = false;
71 bool opt_filter_trace = false;
72 char opt_X10_port[2];
73 bool opt_monitor = false;
74
75 void
76 no_gdb(const char* pszPort, int nBaud, 
77        CeCosSocket::FilterFunc *pSerialToSocketFilterFunc,
78        void *pParam, bool *pbStop)
79 {
80   fprintf(stderr, "no_gdb, listening on %s\n",pszPort);
81   
82   CeCosSocket dummy_socket;
83   CeCosSerial serial;
84   serial.SetBlockingReads(false);
85   bool rc=false;
86   
87   // Open serial device.
88   if (!serial.Open(pszPort,nBaud)){
89     ERROR("Couldn't open port %s\n",pszPort);
90   } else {
91     // Flush the serial buffer.
92     serial.Flush();
93     
94     serial.ClearError();
95     enum {BUFSIZE=8192};
96     void *pBuf=malloc(BUFSIZE);
97     rc=true;
98     while(rc && (0==pbStop || !(*pbStop))){
99       unsigned int nRead=0;
100       
101       for(;;) {
102         if(serial.Read(pBuf,BUFSIZE,nRead)){
103           if(nRead>0){
104             break;
105           }
106           CeCosThreadUtils::Sleep(1);
107         } else {
108           fprintf(stderr, "Serial read failed (%d)\n", errno);
109         }
110       }
111       
112       if(pSerialToSocketFilterFunc){
113         rc=pSerialToSocketFilterFunc(pBuf,nRead,serial,dummy_socket,
114           pParam);
115       }
116     }
117     free(pBuf);
118   }
119 }
120
121 int
122 main(int argc, char** argv)
123 {
124   int nSock = 0;
125   int baud_rate, nTcpPort;
126   
127   bool opt_no_gdb = false;
128   char* ser_port;
129   int i=1;
130   if(!CeCosTestUtils::CommandLine(argc, argv, false)){
131     goto Usage;
132   }
133   
134   while(i<argc){
135     if(argv[i][0]=='-'){
136       switch(argv[i][1]){
137       case 't':
138         // redundant - -v does this
139         CeCosTrace ::EnableTracing(CeCosTrace::TRACE_LEVEL_TRACE);
140         break;
141       case 'f':
142         opt_filter_trace = true;
143         break;
144       case 'S':
145         opt_ser_debug = true;
146         break;
147       case 'm':
148         opt_monitor = true;
149         break;
150       case 'n':
151         opt_no_gdb = true;
152         // fall through! Output on console when no GDB.
153       case 'c':
154         opt_console_output = true;
155         break;
156       case '0':
157         opt_null_filter = true;
158         break;
159       case 'X':
160         // X-10 port to reset when connection drops
161         opt_X10_reset = true;
162         opt_X10_port[0] = argv[i][2];
163         opt_X10_port[1] = argv[i][3];
164         break;
165       default:
166         fprintf(stderr,"Unrecognized switch %s\n",argv[i]);
167         goto Usage;
168         break;
169       }
170       for(int j=i;j<argc;j++){
171         argv[j]=argv[j+1];
172       }
173       argc--;
174       argv[argc]=0;
175     } else {
176       i++;
177     }
178   }
179   
180   if(!((3==argc && opt_no_gdb) || (4==argc && !opt_no_gdb)))
181   {
182     goto Usage;
183   }
184   
185   if (opt_no_gdb) {
186     ser_port = argv[1];
187     baud_rate=atoi(argv[2]);
188   } else {
189     nTcpPort=atoi(argv[1]);
190     if(0==nTcpPort){
191       fprintf(stderr,"Invalid port %s\n",argv[1]);
192       return main(0,argv); // Provoke usage message
193     }
194     
195     ser_port = argv[2];
196     baud_rate=atoi(argv[3]);
197     
198     nSock = CeCosSocket::Listen(nTcpPort);
199     if (-1 == nSock) {
200       fprintf(stderr, "Couldn't access socket.\n");
201       throw "listen failed";
202     }
203   }
204   
205   
206   if (opt_monitor) {
207       fprintf(stdout, "Monitor mode - will not interact with data streams...\n");
208
209       for(;;) {
210       
211           CeCosTestMonitorFilter* host_filter = 
212               new CeCosTestMonitorFilter();
213           CeCosTestMonitorFilter* target_filter = 
214               new CeCosTestMonitorFilter();
215
216           // Set filter directions
217           host_filter->SetOrigin(CeCosTestMonitorFilter::MF_HOST);
218           target_filter->SetOrigin(CeCosTestMonitorFilter::MF_TARGET);
219           
220           // Enable filters
221           host_filter->SetVerbose(true);
222           target_filter->SetVerbose(true);
223
224           // Set filter functions
225           CeCosSocket::FilterFunc *host_filter_function = 
226               &SerialMonitorFunction;
227           CeCosSocket::FilterFunc *target_filter_function = 
228               &SerialMonitorFunction;
229           
230           try {
231               CeCosSocket::ConnectSocketToSerial(nSock, ser_port, 
232                                                      baud_rate, 
233                                                      target_filter_function, 
234                                                      (void*)target_filter, 
235                                                      host_filter_function, 
236                                                      (void*)host_filter,
237                                                      NULL);
238           } 
239           catch (const char* p) {
240               fprintf(stderr, "Caught filter crash: %s\n", p);
241           }
242           
243           delete target_filter;
244           delete host_filter;
245       }
246   }
247   
248   for(;;) {
249     CeCosTestSerialFilter* serial_filter = 
250       new CeCosTestSerialFilter();
251     CeCosTestDownloadFilter* download_filter = 
252       new CeCosTestDownloadFilter();
253     
254     // Set filter configuration
255     serial_filter->SetFilterTrace(opt_filter_trace);
256     serial_filter->SetSerialDebug(opt_ser_debug);
257     serial_filter->SetConsoleOutput(opt_console_output);
258     
259     // Set download filter configuration
260     download_filter->SetFilterTrace(opt_filter_trace);
261     download_filter->SetSerialDebug(opt_ser_debug);
262     
263     // Set serial side filter
264     CeCosSocket::FilterFunc *ser_filter_function = 
265       &SerialFilterFunction;
266     if (opt_null_filter)
267       ser_filter_function = NULL;
268     
269     // Set socket side filter
270     CeCosSocket::FilterFunc *sock_filter_function =
271       &DownloadFilterFunction;
272     
273     try {
274       if (opt_no_gdb)
275         no_gdb(ser_port, baud_rate, ser_filter_function, 
276         (void*)serial_filter, NULL);
277       else
278         CeCosSocket::ConnectSocketToSerial(nSock, ser_port, 
279         baud_rate, 
280         ser_filter_function, 
281         (void*)serial_filter, 
282         sock_filter_function, 
283         (void*)download_filter,
284         NULL);
285     } 
286     catch (const char* p) {
287       fprintf(stderr, "Caught filter crash: %s\n", p);
288     }
289     
290     if (opt_X10_reset) {
291       char X10_cmd[80];
292       sprintf(X10_cmd, "/usr/unsupported/bin/x10cli x10 5000 %c %c", 
293         opt_X10_port[0], opt_X10_port[1]);
294       system(X10_cmd);
295     }
296     
297     delete serial_filter;
298     delete download_filter;
299   }
300   
301 //  return 0;
302   
303 Usage:
304   const char *pszMe="ser_filter";
305   fprintf(stderr,"Usage: %s [-c -S -0 -Xab] TcpIPport SerialPort BaudRate\n"
306     " or:   %s -n [-c -S -0 -Xab] SerialPort BaudRate\n"
307     " Switches:\n"
308     " -f: Enable filter output tracing.\n"
309     " -S: Output data read from serial line.\n"
310     " -c: Output data on console instead of via GDB.\n"
311     " -m: Work only as a monitor filter. Implies -c.\n"
312     " -n: No GDB.\n"
313     " -0: Use null filter.\n"
314     " -Xab: Reset X-10 Port 'a b' when TCP connection breaks\n",pszMe,pszMe);
315   CeCosTestUtils::UsageMessage();
316    
317   return 1;
318 }