Rev Author Line No. Line
2697 miho 1 // MLAB Xilinx Virtual Cable Network Server
2 // ----------------------------------------
3 //
2941 miho 4 // (c) miho 2012, 2013 http://www.mlab.cz/PermaLink/XVC_SOFTWARE
2697 miho 5 //
6 // This program if free.
7 //
8 //
9 // History:
10 //
11 // 1.00 2012_09 Proof of concept (no configuration, not for public release)
12 // 1.01 2012_09 Added parameter for device selection
13 // 1.02 2012_12 Error handling and debugged
14 // 1.03 2012_12 Release version ready to publish
2935 miho 15 // 1.04 2013_04 Socket Bind Error with explanation (multiple instance of XVC Server)
2942 miho 16 // 1.05 2013_04 Test FTDI cable during wait for Accept (to stop the server immediately when cable is disconnected)
17 // 1.06 2013_04 Added support for Linux (thanks to Martin Poviser)
18 // 1.07 2013_04 Rewritten Host Address function for Linux (function gethostbyname returns 127.0.1.1 on Debian systems)
19 // Solved compatibility problems on Linux (FT_SetLatncyTimer requires delay, udev problem with ftdi_sio driver)
2697 miho 20 //
21 //
22 // Purpose:
23 //
24 // XILINX development software (ISE, WebPack) supports several types of JTAG programming
25 // cables. Among them there is one particularly interesting. It is Xilinx Virtual Cable
26 // which uses (documented) XVC network protocol to send JTAG commands across TCP/IP network.
27 // So it is possible to realize own hardware/software and have it directly supported by
28 // XILINX development software (both IMPACT and ChipScope).
29 //
30 // This program listens TCP data send by XILINX ISE IMAPACT (or ChipScope) and sends it
31 // to the JTAG device (typically FPGA) connected to FTDI USB Chip. You can use ordinary
32 // USB/RS232 translator based on FT232R chip or you can use our own module from
33 // http://www.mlab.cz/PermaLink/XVC_FT220X
34 //
35 // Target device JTAG port is connected to pins on FTDI USB chip. Program writes to standard
36 // output Which pins are used. Program writes what to set in ISE to enable XVC plugin.
37 //
38 //
39 // Environment:
40 //
41 // This is Win32 Console Application and run in WinXP / Win7 / Win8 both 32 and 64 bit.
42 //
43 // Program needs to listen to the network so it is necessary to allow doing so. In Windows
44 // firewall configuration enable networking for the exe file.
45 // WinXP: run as Administrator c:\WINDOWS\System32\firewall.cpl and add the exe file
46 // Win7: the system asks directly to do so
47 //
48 //
49 // Technology:
50 //
51 // The program uses Windows WINSOCK2 library for network communication
52 // and FTDI ftd2xx library for communication with FTDI USB chip.
53 // It can be staticly linked to minimize dependencies on libraries.
54 // Program requires FTDI drivers installed.
55 // Because of the usage of standard libraries you don't need to solve how to sign drivers.
56 //
57 // The program was debug with FT232R and FT220X device.
58 // It should work with any similar FTDI USB chip.
59 //
60 // XVC protocol is documented (you have to ask XILINX support to gain access).
61 // The program is inspired by the work http://debugmo.de/2012/02/xvcd-the-xilinx-virtual-cable-daemon/
62 // Ask Google about Xilinx Virtual Cable.
63 //
64 //
2940 miho 65 // Compilation for Windows:
2697 miho 66 //
67 // MS Visual C++ 2010 Express (free, registration required)
68 // Create new empty project for Win32 Console Application and name project mlab_xvcd (to build mlab_xvcd.exe)
69 // Header Files / Add / Existing Items - all .h files
70 // Source Files / Add / Existing Items - all .cpp files
2940 miho 71 // Library Files / Add / Existing Items - all .lib .h files from lib_win32 directory
2697 miho 72 // Select Release version (no debug info)
73 // Set static linkage Project Properties / Configuration Release / Configuration Properties
74 // / Code Generation / Runtime Library = Multithreaded (/MT)
75 //
2940 miho 76 // Compilation for Linux:
2697 miho 77 //
2940 miho 78 // On Ubuntu 12.04LTS just run the .sh file
79 //
2697 miho 80 // Problems:
81 //
82 // Programming of SPI FLASH configuration memory connected to FPGA does not work. No idea why.
83 // It does not work for internal FLASH of Spartan XC3SxxAN either.
84 //
85 //
86 // Possible improvements:
87 //
88 // External definition of JTAG pins.
2933 miho 89 // Enable Socket Number (to be able to run multiple XVC Servers), now it is constant XVC_TCP_PORT (should be only a default)
2697 miho 90  
91  
92 // Library Definitions
93 // -------------------
94  
95 #undef UNICODE
96 #define WIN32_LEAN_AND_MEAN
97  
98 #include "mlab_xvcd.h" // Program Configuration
99 #include <stdlib.h> // Standard Library (exit, atoi, ...)
100 #include <stdio.h> // Standard IO (printf, ...)
101 #include <signal.h> // CTRL+C handling
102  
2940 miho 103 #ifdef WIN32
104  
105 #include <windows.h> // Windows Console Application
106 #include <winsock2.h> // Windows WinSock2
107 #include <ws2tcpip.h> // Windows WinSock2
108  
2697 miho 109 // Link with library
110 #pragma comment (lib, "Ws2_32.lib")
2940 miho 111 //#pragma comment (lib, "../lib_win32/ftd2xx.lib") // Add this file to Resources
2697 miho 112  
2940 miho 113 #else // not WIN32
114  
115 #include "lib_linux_i386/WinTypes.h"
116 #include <sys/types.h>
117 #include <sys/socket.h>
118 #include <fcntl.h>
119 #include <errno.h>
120 #include <unistd.h>
121 #include <netdb.h>
2942 miho 122 #include <net/if.h>
123 #include <sys/ioctl.h>
124 #include <arpa/inet.h>
2940 miho 125  
126 #endif
127  
2697 miho 128 #define XVC_RX_BUFLEN (XVC_JTAG_LEN/8*2+20) // Length of receive buffer in bytes (command+length+TMSbuffer+TDIbuffer)
129 #define XVC_TX_BUFLEN (XVC_JTAG_LEN/8) // Length of transmit buffer in bytes (TDObuffer)
130  
2940 miho 131 #ifdef WIN32
2697 miho 132  
2940 miho 133 typedef int socklen_t;
134  
135 #else //not WIN32
136  
137 typedef int SOCKET;
138  
139 #define SOCKET_ERROR -1
140 #define INVALID_SOCKET -1
141  
142 void closesocket(int socket)
143 {
144 close(socket);
145 }
146  
147 void WSACleanup()
148 {
149 }
150  
151 int WSAGetLastError()
152 {
153 return errno;
154 }
155  
156 #endif
157  
2697 miho 158 // JTAG state machine
159 // ------------------
160  
161 // JTAG States
162 enum
163 {
164 test_logic_reset, run_test_idle, // Starts from 0
165  
166 select_dr_scan, capture_dr, shift_dr,
167 exit1_dr, pause_dr, exit2_dr, update_dr,
168  
169 select_ir_scan, capture_ir, shift_ir,
170 exit1_ir, pause_ir, exit2_ir, update_ir,
171  
172 num_states
173 };
174  
175  
176 // JTAG State Machine transfer Function
177 static int jtagStep(int state, int tms)
178 {
179 static const int next_state[num_states][2] =
180 {
181 /* JTAG State -->> New State */
182 /* -------------------------------------------------------------*/
183 /* | TMS=0 | TMS=1 */
184 /* -------------------------------------------------------------*/
185 /* [test_logic_reset] -> */ { run_test_idle, test_logic_reset },
186 /* [run_test_idle] -> */ { run_test_idle, select_dr_scan },
187 /* [select_dr_scan] -> */ { capture_dr, select_ir_scan },
188 /* [capture_dr] -> */ { shift_dr, exit1_dr },
189 /* [shift_dr] -> */ { shift_dr, exit1_dr },
190 /* [exit1_dr] -> */ { pause_dr, update_dr },
191 /* [pause_dr] -> */ { pause_dr, exit2_dr },
192 /* [exit2_dr] -> */ { shift_dr, update_dr },
193 /* [update_dr] -> */ { run_test_idle, select_dr_scan },
194 /* [select_ir_scan] -> */ { capture_ir, test_logic_reset },
195 /* [capture_ir] -> */ { shift_ir, exit1_ir },
196 /* [shift_ir] -> */ { shift_ir, exit1_ir },
197 /* [exit1_ir] -> */ { pause_ir, update_ir },
198 /* [pause_ir] -> */ { pause_ir, exit2_ir },
199 /* [exit2_ir] -> */ { shift_ir, update_ir },
200 /* [update_ir] -> */ { run_test_idle, select_dr_scan }
201 };
202  
203 return next_state[state][tms];
204 }
205  
206  
207 int handleData(SOCKET ClientSocket)
208 {
209  
210 bool seen_tlr = false;
211 bool jtagError = false;
212  
213 static int jtag_state;
214  
215 do
216 {
217 int iResult;
218  
219 // Read Command
220 char command[16];
2940 miho 221 unsigned int commandLen = 0;
2697 miho 222  
223 // Read String terminated by ':'
224 do
225 {
226 iResult = recv(ClientSocket, command+commandLen, 1, 0);
227 if (iResult==0)
228 {
229 printf("\n Connection Closed\n\n");
230 return -1;
231 }
232 else if (iResult==1)
233 {
234 commandLen++;
235 }
236 else
237 {
238 fprintf(stderr, "Error Reading Command\n");
239 return -2;
240 }
241 }
242 while (command[commandLen-1]!=':' && commandLen<sizeof(command)-1 );
243 command[commandLen] = char(0);
244  
245 if (0==strncmp(command, "shift:", sizeof(command)))
246 {
247  
248 }
249 else
250 {
251 fprintf(stderr, "Invalid Command '%s'\n", command);
252 return -2;
253 }
254  
255 // Read Length (in bits, 32bit integer)
256 int len;
257  
258 iResult = recv(ClientSocket, (char *)&len, 4, 0); // pøepsat pøenositelnì
259 if (iResult==0)
260 {
261 printf("\n Connection Closed\n\n");
262 return -1;
263 }
264 if (iResult != 4)
265 {
266 fprintf(stderr, "Reading Length Failed\n");
267 return -2;
268 }
269  
270 char buffer[2048];
271  
272 // Read Data (data string for TMS and TDI)
2940 miho 273 unsigned int nr_bytes = (len + 7) / 8;
2697 miho 274 if (nr_bytes * 2 > sizeof(buffer))
275 {
276 fprintf(stderr, "Buffer Size Exceeded\n");
277 return -2;
278 }
279  
2940 miho 280 unsigned int iReceivedBytes=0;
2697 miho 281 while (iReceivedBytes<nr_bytes * 2)
282 {
283 iResult = recv(ClientSocket, buffer+iReceivedBytes, nr_bytes * 2 - iReceivedBytes, 0);
284 if (iResult==0)
285 {
286 printf("\n Connection Closed\n\n");
287 return -1;
288 }
289 if (iResult<=0)
290 {
291 fprintf(stderr, "Reading Data Failed %d %d\n", iResult, nr_bytes * 2);
292 return -2;
293 }
294 iReceivedBytes += iResult;
295 }
296  
297 char result[1024];
298 memset(result, 0, nr_bytes);
299  
300 // Deal with JTAG
301  
302 // Only allow exiting if the state is rti and the IR
303 // has the default value (IDCODE) by going through test_logic_reset.
304 // As soon as going through capture_dr or capture_ir no exit is
305 // allowed as this will change DR/IR.
306 seen_tlr = (seen_tlr || jtag_state == test_logic_reset) && (jtag_state != capture_dr) && (jtag_state != capture_ir);
307  
308 // Due to a weird bug(??) xilinx impacts goes through another "capture_ir"/"capture_dr" cycle after
309 // reading IR/DR which unfortunately sets IR to the read-out IR value.
310 // Just ignore these transactions.
311 if ((jtag_state == exit1_ir && len == 5 && buffer[0] == 0x17) || (jtag_state == exit1_dr && len == 4 && buffer[0] == 0x0b))
312 {
313 // printf("Ignoring Bogus jtag State movement at jtag_state %d\n", jtag_state);
314 }
315 else
316 {
317 for (int i = 0; i < len; ++i)
318 {
319 //
320 // Do the actual cycle.
321 //
322 int tms = !!(buffer[i/8] & (1<<(i&7)));
323 //
324 // Track the state.
325 //
326 jtag_state = jtagStep(jtag_state, tms);
327 }
328 if (jtagScan((unsigned char *) buffer, (unsigned char *) buffer + nr_bytes, (unsigned char *) result, len) < 0)
329 {
330 //fprintf(stderr, "jtagScan failed\n");
331 // Can't stop now, have to sent (any) answer not to hung the IMPACT
332 jtagError = true;
333 }
334 }
335  
336 // Send the Ansver
337 iResult = send(ClientSocket, result, nr_bytes, 0 );
338 if (iResult == SOCKET_ERROR)
339 {
340 printf("Send Failed with Error: %d\n", WSAGetLastError());
341 closesocket(ClientSocket);
342 WSACleanup();
343 return -2;
344 }
345 // printf("Bytes Sent: %d\n", iSendResult);
346 // printf("jtag state %d\n", jtag_state);
347 }
348 while (!(seen_tlr && jtag_state == run_test_idle));
349  
350 return jtagError ? -2 : 0;
351 }
352  
353  
354 // Stop Handler - switch JTAG port off and stop program
2940 miho 355 void stopHandler(int)
2697 miho 356 {
357 jtagClosePort();
358 exit(1);
359 }
360  
361  
362 // Print help and stop program with error
363 void Help(char *progName)
364 {
365 fprintf(stderr, "Bad Parameters\n");
366 fprintf(stderr, "\n");
367 fprintf(stderr, "Usage: %s [arg]\n", progName);
368 fprintf(stderr, "\n");
369 fprintf(stderr, " Where [arg] is one of: \n");
370 fprintf(stderr, " -d Description Fing FTDI device by Description\n");
371 fprintf(stderr, " -l Location Fing FTDI device by Loaction\n");
372 fprintf(stderr, " -s Serial_number Fing FTDI device by it's SN\n");
373 fprintf(stderr, " -n Number Use N-th FTDI device\n");
374 fprintf(stderr, " The first FTDI device is used if no argument\n");
375 exit(2);
376 }
377  
378  
2940 miho 379 int main(int argc, char *argv[])
2697 miho 380 {
381 // Variables
382 bool verbose = true;
383  
384 // Program Info
385 printf("\n");
386 printf("Xilinx Virtual Cable Network Server\n");
387 printf("===================================\n");
2941 miho 388 printf("(c) miho " YEAR " v " VERSION "\n\n");
2697 miho 389  
390 // Get program name
391 char *cp;
392 char *progName;
393 cp = argv[0];
394 progName=cp;
395 while (cp[0]!='\0')
396 {
397 if (cp[0]=='/' || cp[0]=='\\')
398 progName=cp+1;
399 cp++;
400 }
401  
402 // Process command line params
403 char *findDeviceByStr = 0; // String parameter
404 int findDeviceBy = 0; // What does the string means
405  
406 if (argc>1)
407 {
408 if (argc==3)
409 {
410 findDeviceByStr = argv[2];
411 if (strcmp(argv[1], "-d")==0)
412 {
413 findDeviceBy = OPEN_BY_DESCRIPTION;
414 }
415 else if (strcmp(argv[1], "-l")==0)
416 {
417 findDeviceBy = OPEN_BY_LOCATION;
418 }
419 else if (strcmp(argv[1], "-s")==0)
420 {
421 findDeviceBy = OPEN_BY_SERIAL_NUMBER;
422 }
423 else if (strcmp(argv[1], "-n")==0)
424 {
425 findDeviceBy = 0;
426 }
427 else
428 {
429 Help(progName);
430 }
431 }
432 else
433 {
434 Help(progName);
435 }
436 }
437 else
438 {
439 // Empty String - find device by number and number is empty
440 findDeviceBy = 0;
2940 miho 441 findDeviceByStr = (char *)"";
2697 miho 442 }
443  
444 // Find, Init and Open FTDI USB Chip
445 if (jtagOpenPort(findDeviceBy, findDeviceByStr)<0) {
446 // No Device Found
447 fprintf(stderr, "ERROR: No Device Found\n");
448 return -1;
449 }
450  
451 // Signal Handler (for CRTL+C)
452 signal(SIGINT, &stopHandler);
453  
454 printf("Starting Network Server\n");
455 int iResult;
456  
457 SOCKET ListenSocket = INVALID_SOCKET;
458 SOCKET ClientSocket = INVALID_SOCKET;
459  
2940 miho 460 #ifdef WIN32
2697 miho 461 // Initialize Winsock
2940 miho 462 WSADATA wsaData;
2697 miho 463 iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
464 if (iResult != 0)
465 {
466 fprintf(stderr, "WSAStartup failed with error: %d\n", iResult);
467 jtagClosePort();
468 return -2;
469 }
2940 miho 470 #endif
2697 miho 471  
2942 miho 472 // Display HostName
2697 miho 473 char sMyName[255];
474 gethostname(sMyName, sizeof(sMyName));
475 printf(" Host Name %s\n", sMyName);
2942 miho 476  
477 // Display Address
478 #ifdef WIN32
2697 miho 479 hostent * pHostInfo;
480 pHostInfo = gethostbyname(sMyName);
481 printf(" Network Name %s\n", pHostInfo->h_name);
482 if (pHostInfo->h_length>0 && pHostInfo->h_length<=16)
483 {
484 printf(" Host Address ");
485 for (int i=0; i<pHostInfo->h_length-1; i++)
486 {
487 printf("%d.", (unsigned char)pHostInfo->h_addr_list[0][i]);
488 }
489 printf("%d\n", (unsigned char)pHostInfo->h_addr_list[0][pHostInfo->h_length-1]);
490 }
2942 miho 491 #else
492 int TempSocket;
493 struct ifreq ifreqs[20];
494 struct ifconf ic;
2697 miho 495  
2942 miho 496 ic.ifc_len = sizeof ifreqs;
497 ic.ifc_req = ifreqs;
498  
499 TempSocket = socket(AF_INET, SOCK_DGRAM, 0);
500 if (TempSocket < 0) {
501 perror("socket");
502 return -2;
503 }
504  
505 if (ioctl(TempSocket, SIOCGIFCONF, &ic) < 0) {
506 perror("SIOCGIFCONF");
507 return -2;
508 }
509  
510 for (int i = 0; i < ic.ifc_len/sizeof(struct ifreq); ++i)
511 {
512 if (ifreqs[i].ifr_name[0]!='l')// remove lo
513 printf(" Host Address %s: %s\n",
514 ifreqs[i].ifr_name,
515 inet_ntoa(((struct sockaddr_in*)&ifreqs[i].ifr_addr)->sin_addr));
516 }
517 #endif
518  
2697 miho 519 // Create Protocol Structure
520 struct addrinfo hints;
2940 miho 521 memset(&hints, 0, sizeof(hints));
2697 miho 522 hints.ai_family = AF_INET; // IP6
523 hints.ai_socktype = SOCK_STREAM; // Reliable two-way connection
524 hints.ai_protocol = IPPROTO_TCP; // Protocol TCP
525 hints.ai_flags = AI_PASSIVE;
526  
527 // Resolve the server address and port (allocate structure "result")
528 struct addrinfo *result = NULL;
529 iResult = getaddrinfo(NULL, XVC_TCP_PORT, &hints, &result);
530 if ( iResult != 0 )
531 {
532 fprintf(stderr, "getaddrinfo failed with error: %d\n", iResult);
533 WSACleanup();
534 jtagClosePort();
535 return -2;
536 }
537  
538 // Create a SOCKET
539 ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
540 if (ListenSocket == INVALID_SOCKET)
541 {
2940 miho 542 fprintf(stderr, "socket failed with error: %d\n", WSAGetLastError());
2697 miho 543 freeaddrinfo(result);
544 WSACleanup();
545 jtagClosePort();
546 return -2;
547 }
548  
549 // Bind the SOCKED (assign the address)
550 iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
551 if (iResult == SOCKET_ERROR)
552 {
2933 miho 553 int LastError=WSAGetLastError();
554 fprintf(stderr, "Bind failed with error: %d\n", LastError);
2940 miho 555 #ifdef WIN32
556 if (LastError==WSAEADDRINUSE)
557 #else
558 if (LastError==EADDRINUSE)
559 #endif
560 fprintf(stderr, "Trying to start second instance of XVC Server?\n");
2697 miho 561 freeaddrinfo(result);
562 closesocket(ListenSocket);
563 WSACleanup();
564 jtagClosePort();
565 return -2;
566 }
567  
568 if (verbose)
569 {
570 printf(" Bound Socket %s\n", XVC_TCP_PORT);
571 }
572  
573 // Help for user
574 printf(" Set in IMPACT xilinx_xvc host=%s:%s disableversioncheck=true\n", sMyName, XVC_TCP_PORT);
575  
576 freeaddrinfo(result);
577  
578 // Listen SOCKET
579 iResult = listen(ListenSocket, SOMAXCONN);
580 if (iResult == SOCKET_ERROR)
581 {
2933 miho 582 fprintf(stderr, "listen failed with error: %d\n", WSAGetLastError());
2697 miho 583 closesocket(ListenSocket);
584 WSACleanup();
585 jtagClosePort();
586 return -2;
587 }
588  
589 printf("\n");
590  
591 do
592 {
593 printf(" Listen\n");
594 jtagSetLED(true);
595  
2935 miho 596 // Set ListenSocket to non-blocking mode
597 // We need during waiting for Accept to detect FTDI disconnect
2940 miho 598  
599 #ifdef WIN32
2935 miho 600 u_long iMode = 1;
601 iResult = ioctlsocket(ListenSocket, FIONBIO, &iMode);
602 if (iResult != NO_ERROR)
603 {
604 fprintf(stderr, "ioctlsocket failed with error: %ld\n", iResult);
605 WSACleanup();
606 jtagClosePort();
607 return -2;
608 }
2940 miho 609 #else
610 iResult = fcntl(ListenSocket, F_GETFL, 0);
611 if (iResult < 0 || fcntl(ListenSocket, F_SETFL, iResult | O_NONBLOCK) < 0)
612 {
613 fprintf(stderr, "fcntl failed with error: %d\n", errno);
614 jtagClosePort();
615 return -2;
616 }
617 #endif
2935 miho 618  
619 // Accept a client SOCKET (wait for Accept)
2697 miho 620 sockaddr ClientSocetAddr;
2940 miho 621 socklen_t ClientSocetAddrLen = sizeof(sockaddr);
2935 miho 622 do
2697 miho 623 {
2935 miho 624 // Try Accept (non-blocking)
625 ClientSocket = accept(ListenSocket, &ClientSocetAddr, &ClientSocetAddrLen);
626 if (ClientSocket == INVALID_SOCKET)
627 {
628 // Accept Error
2940 miho 629 #ifdef WIN32
2935 miho 630 if (WSAGetLastError() != WSAEWOULDBLOCK)
2940 miho 631 #else
632 if (WSAGetLastError() != EAGAIN && WSAGetLastError() != EWOULDBLOCK)
633 #endif
2935 miho 634 {
635 fprintf(stderr, "accept failed with error: %d\n", WSAGetLastError());
636 closesocket(ListenSocket);
637 WSACleanup();
638 jtagClosePort();
639 return -2;
640 }
641 // Not yet Accepted
642 {
643 // Check FTDI
644 if (!CheckCable())
645 {
2940 miho 646 fprintf(stderr, "XVC Cable unexpectedly disconnected\n");
2935 miho 647 closesocket(ListenSocket);
648 WSACleanup();
649 jtagClosePort();
650 return -2;
651 }
652 // Sleep some time (do not eat CPU time for nothong)
2940 miho 653 #ifdef WIN32
2935 miho 654 Sleep(100); //ms
2940 miho 655 #else
656 usleep(100000); //us
657 #endif
2935 miho 658 }
659 }
660 }
661 while (ClientSocket == INVALID_SOCKET);
662  
663 // Set (Accepted) Socket to blocking mode
2940 miho 664  
665 #ifdef WIN32
2935 miho 666 iMode = 0;
667 iResult = ioctlsocket(ClientSocket, FIONBIO, &iMode);
668 if (iResult != NO_ERROR)
669 {
670 fprintf(stderr, "ioctlsocket failed with error: %ld\n", iResult);
2697 miho 671 WSACleanup();
672 jtagClosePort();
673 return -2;
674 }
2940 miho 675 #else
676 iResult = fcntl(ListenSocket, F_GETFL, 0);
677 if (iResult < 0 || fcntl(ListenSocket, F_SETFL, iResult & ~O_NONBLOCK) < 0)
678 {
679 fprintf(stderr, "fcntl failed with error: %d\n", errno);
680 jtagClosePort();
681 return -2;
682 }
683 #endif
2697 miho 684  
685 // Print Accepted + Address
686 printf(" Accepted ");
687 jtagSetLED(false);
688 for (int i=2; i<2+4-1; i++)
689 {
690 printf("%d.", (unsigned char)ClientSocetAddr.sa_data[i]);
691 }
692 printf("%d:%d\n", (unsigned char)ClientSocetAddr.sa_data[2+4-1], (unsigned char)ClientSocetAddr.sa_data[0]*256+(unsigned char)ClientSocetAddr.sa_data[1]);
693  
694 // Process Data until the peer shuts down the connection
695 int Cnt = 0;
696 printf(" Handle Data ");
697 do
698 {
699 iResult = handleData(ClientSocket);
700 if (iResult>=0)
701 {
702 printf(".");
2940 miho 703 fflush(stdout);
2697 miho 704 Cnt++;
705 if (Cnt>40)
706 {
707 Cnt = 0;
708 printf("\n ");
709 }
710 }
711 }
712 while (iResult >= 0);
713  
714 // Connection Closed by peer
715 if (iResult==-1)
716 {
717 // JTAG port
718 jtagSetIdle();
719 }
720  
721 // Error - shutdown the connection
722 if (iResult==-2)
723 {
724 fprintf(stderr, " Disconnect\n");
2940 miho 725 #ifdef WIN32
2697 miho 726 iResult = shutdown(ClientSocket, SD_SEND);
2940 miho 727 #else
728 iResult = shutdown(ClientSocket, SHUT_WR);
729 #endif
2697 miho 730 if (iResult == SOCKET_ERROR)
731 {
732 fprintf(stderr, "shutdown failed with error: %d\n", WSAGetLastError());
733 }
734 iResult=-2; // Error
735 }
736  
737 // cleanup
738 closesocket(ClientSocket);
739  
740 }
741 // If not Error Listen Again
742 while (iResult!=-2);
743  
744 // cleanup
745 closesocket(ListenSocket);
746 WSACleanup();
747 jtagClosePort();
748  
749 return 1;
750 }