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