Rev 1134 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
819 | DimkaM | 1 | #include "std.h" |
2 | #include "emul.h" |
||
3 | #include "vars.h" |
||
4 | #include "zxusbnet.h" |
||
885 | lvd | 5 | #include <iphlpapi.h> |
819 | DimkaM | 6 | |
7 | #define buf_size 8*1024 |
||
8 | |||
9 | //#define dbgmod |
||
10 | #ifdef dbgmod |
||
11 | #define DPRINTF printf |
||
12 | #else |
||
13 | #define DPRINTF(pa,pb) |
||
14 | #endif // dbgmod |
||
15 | |||
16 | #define WRITE_REG_FUNC(f_n) void f_n(sInfoStruct * s, u_char d, u_char z) |
||
17 | #define READ_REG_FUNC(f_n) u_char f_n(sInfoStruct * s, u_char z) |
||
18 | |||
19 | |||
20 | enum class TCP_STATE{ |
||
21 | NONE, CLIENT_CONNECTED, LISTEN_CONNECTED, CLIENT, LISTEN, CLOSED |
||
22 | }; |
||
23 | |||
24 | /************************************/ |
||
25 | /* The bit of MR regsiter defintion */ |
||
26 | /************************************/ |
||
27 | #define MR_DBW (1 << 15) /**< Data bus width bit of MR. */ |
||
28 | #define MR_MPF (1 << 14) /**< Mac layer pause frame bit of MR. */ |
||
29 | #define MR_WDF(X) ((X & 0x07) << 11) /**< Write data fetch time bit of MR. */ |
||
30 | #define MR_RDH (1 << 10) /**< Read data hold time bit of MR. */ |
||
31 | #define MR_FS (1 << 8) /**< FIFO swap bit of MR. */ |
||
32 | #define MR_RST (1 << 7) /**< S/W reset bit of MR. */ |
||
33 | #define MR_MT (1 << 5) /**< Memory test bit of MR. */ |
||
34 | #define MR_PB (1 << 4) /**< Ping block bit of MR. */ |
||
35 | #define MR_PPPoE (1 << 3) /**< PPPoE bit of MR. */ |
||
36 | #define MR_DBS (1 << 2) /**< Data bus swap of MR. */ |
||
37 | #define MR_IND (1 << 0) /**< Indirect mode bit of MR. */ |
||
38 | |||
39 | |||
40 | /***************************************/ |
||
41 | /* The bit of Sn_MR regsiter defintion */ |
||
42 | /***************************************/ |
||
43 | #define Sn_MR_ALIGN (1 << 8) /**< Alignment bit of Sn_MR. */ |
||
44 | #define Sn_MR_MULTI (1 << 7) /**< Multicasting bit of Sn_MR. */ |
||
45 | #define Sn_MR_MF (1 << 6) /**< MAC filter bit of Sn_MR. */ |
||
46 | #define Sn_MR_IGMPv (1 << 5) /**< IGMP version bit of Sn_MR. */ |
||
47 | #define Sn_MR_ND (1 << 5) /**< No delayed ack bit of Sn_MR. */ |
||
48 | #define Sn_MR_CLOSE 0x00 /**< Protocol bits of Sn_MR. */ |
||
49 | #define Sn_MR_TCP 0x01 /**< Protocol bits of Sn_MR. */ |
||
50 | #define Sn_MR_UDP 0x02 /**< Protocol bits of Sn_MR. */ |
||
51 | #define Sn_MR_IPRAW 0x03 /**< Protocol bits of Sn_MR. */ |
||
52 | #define Sn_MR_MACRAW 0x04 /**< Protocol bits of Sn_MR. */ |
||
53 | #define Sn_MR_PPPoE 0x05 /**< Protocol bits of Sn_MR. */ |
||
54 | |||
55 | /******************************/ |
||
56 | /* The values of CR defintion */ |
||
57 | /******************************/ |
||
58 | #define Sn_CR_OPEN 0x01 /**< OPEN command value of Sn_CR. */ |
||
59 | #define Sn_CR_LISTEN 0x02 /**< LISTEN command value of Sn_CR. */ |
||
60 | #define Sn_CR_CONNECT 0x04 /**< CONNECT command value of Sn_CR. */ |
||
61 | #define Sn_CR_DISCON 0x08 /**< DISCONNECT command value of Sn_CR. */ |
||
62 | #define Sn_CR_CLOSE 0x10 /**< CLOSE command value of Sn_CR. */ |
||
63 | #define Sn_CR_SEND 0x20 /**< SEND command value of Sn_CR. */ |
||
64 | #define Sn_CR_SEND_MAC 0x21 /**< SEND_MAC command value of Sn_CR. */ |
||
65 | #define Sn_CR_SEND_KEEP 0x22 /**< SEND_KEEP command value of Sn_CR */ |
||
66 | #define Sn_CR_RECV 0x40 /**< RECV command value of Sn_CR */ |
||
67 | #define Sn_CR_PCON 0x23 /**< PCON command value of Sn_CR */ |
||
68 | #define Sn_CR_PDISCON 0x24 /**< PDISCON command value of Sn_CR */ |
||
69 | #define Sn_CR_PCR 0x25 /**< PCR command value of Sn_CR */ |
||
70 | #define Sn_CR_PCN 0x26 /**< PCN command value of Sn_CR */ |
||
71 | #define Sn_CR_PCJ 0x27 /**< PCJ command value of Sn_CR */ |
||
72 | |||
73 | /**********************************/ |
||
74 | /* The values of Sn_SSR defintion */ |
||
75 | /**********************************/ |
||
76 | #define SOCK_CLOSED 0x00 /**< SOCKETn is released */ |
||
77 | #define SOCK_ARP 0x01 /**< ARP-request is transmitted in order to acquire destination hardware address. */ |
||
78 | #define SOCK_INIT 0x13 /**< SOCKETn is open as TCP mode. */ |
||
79 | #define SOCK_LISTEN 0x14 /**< SOCKETn operates as "TCP SERVER" and waits for connection-request (SYN packet) from "TCP CLIENT". */ |
||
80 | #define SOCK_SYNSENT 0x15 /**< Connect-request(SYN packet) is transmitted to "TCP SERVER". */ |
||
81 | #define SOCK_SYNRECV 0x16 /**< Connect-request(SYN packet) is received from "TCP CLIENT". */ |
||
82 | #define SOCK_ESTABLISHED 0x17 /**< TCP connection is established. */ |
||
83 | #define SOCK_FIN_WAIT 0x18 /**< SOCKETn is closing. */ |
||
84 | #define SOCK_CLOSING 0x1A /**< SOCKETn is closing. */ |
||
85 | #define SOCK_TIME_WAIT 0x1B /**< SOCKETn is closing. */ |
||
86 | #define SOCK_CLOSE_WAIT 0x1C /**< Disconnect-request(FIN packet) is received from the peer. */ |
||
87 | #define SOCK_LAST_ACK 0x1D /**< SOCKETn is closing. */ |
||
88 | #define SOCK_UDP 0x22 /**< SOCKETn is open as UDP mode. */ |
||
89 | #define SOCK_IPRAW 0x32 /**< SOCKETn is open as IPRAW mode. */ |
||
90 | #define SOCK_MACRAW 0x42 /**< SOCKET0 is open as MACRAW mode. */ |
||
91 | #define SOCK_PPPoE 0x5F /**< SOCKET0 is open as PPPoE mode. */ |
||
92 | |||
93 | |||
94 | union LONG_CHAR{ |
||
95 | u_long ul; |
||
96 | u_char b[4]; |
||
97 | }; |
||
98 | |||
99 | |||
100 | static struct sInfoStruct |
||
101 | { |
||
102 | SOCKET s; //socket |
||
103 | sockaddr_in sa_in; |
||
104 | u_char PORTR[2]; |
||
105 | WSAEVENT Event; |
||
106 | u_char MR[2]; |
||
107 | u_char CR; |
||
108 | TCP_STATE tcpState; |
||
109 | u_long RX_RSR; |
||
110 | u_char rx[buf_size + 8]; |
||
111 | u_char * rx_ptr; |
||
112 | LONG_CHAR TX_WRSR; |
||
113 | u_char tx[buf_size]; |
||
114 | u_char * tx_ptr; |
||
115 | SOCKET list; //socket |
||
830 | dimkam | 116 | u_char PROTOR; |
847 | DimkaM | 117 | u_char BINDED; |
819 | DimkaM | 118 | }soc[8]; |
847 | DimkaM | 119 | //static char myIP[4]; |
819 | DimkaM | 120 | static sockaddr_in sa_in; |
847 | DimkaM | 121 | static sockaddr_in r_sa_in; |
122 | //static u_long len_test; |
||
819 | DimkaM | 123 | static TIMEVAL select_timeout; |
124 | static u_char stat_regs[0x0100]; |
||
125 | static u_char regs[sizeof(stat_regs)]; |
||
126 | static int ns, iResult; |
||
127 | static u_char data; |
||
847 | DimkaM | 128 | //static char * s_ptr; |
819 | DimkaM | 129 | static fd_set fd_s; |
847 | DimkaM | 130 | //static fd_set fd_s1; |
819 | DimkaM | 131 | static u_long is_blocked = 0, non_blocked = 1; |
132 | WSADATA wsaData; |
||
133 | |||
847 | DimkaM | 134 | void soc_bind(sInfoStruct * s){ |
135 | ZeroMemory(&sa_in, sizeof(sa_in)); |
||
136 | sa_in.sin_family = AF_INET; |
||
884 | DimkaM | 137 | //memcpy(&sa_in.sin_addr.S_un.S_addr, &stat_regs[0x0018], 4); |
138 | char broadcast = '1'; |
||
139 | setsockopt(s->s,SOL_SOCKET,SO_BROADCAST,&broadcast,sizeof(broadcast)); |
||
140 | sa_in.sin_addr.s_addr = htonl(INADDR_ANY);; |
||
847 | DimkaM | 141 | sa_in.sin_port = (s->PORTR[1] << 8) | s->PORTR[0]; |
142 | bind(s->s, (sockaddr *)&sa_in, sizeof(sa_in)); |
||
143 | s->BINDED = 1; |
||
144 | } |
||
145 | |||
819 | DimkaM | 146 | void WizRecv(sInfoStruct * s){ |
147 | if (s->rx_ptr)return; |
||
148 | int len=0; |
||
830 | dimkam | 149 | switch (s->MR[1]){ |
150 | case Sn_MR_TCP: |
||
151 | len = recv(s->s, (char*)&s->rx[2], buf_size, 0); |
||
152 | break; |
||
153 | case Sn_MR_UDP: |
||
847 | DimkaM | 154 | if(s->BINDED == 0) soc_bind(s); |
155 | //ZeroMemory(&r_sa_in, sizeof(r_sa_in)); |
||
156 | iResult = sizeof(r_sa_in); |
||
157 | len=recvfrom(s->s, (char*)&s->rx[8], buf_size, 0, (sockaddr *)&r_sa_in, &iResult); |
||
830 | dimkam | 158 | break; |
159 | case Sn_MR_IPRAW: |
||
847 | DimkaM | 160 | if(s->BINDED == 0) soc_bind(s); |
161 | //ZeroMemory(&r_sa_in, sizeof(r_sa_in)); |
||
162 | iResult = sizeof(r_sa_in); |
||
163 | len=recvfrom(s->s, (char*)&s->rx[6], buf_size, 0, (sockaddr *)&r_sa_in, &iResult); |
||
164 | //printf("res=%d, errno=%d\r\n",len,errno); |
||
830 | dimkam | 165 | break; |
819 | DimkaM | 166 | } |
167 | if(len>0)DPRINTF("Recv %d bytes\r\n", len); |
||
168 | switch (len) |
||
169 | { |
||
170 | case -1: |
||
171 | return; |
||
172 | case 0: |
||
173 | if (s->MR[1] == Sn_MR_TCP) |
||
174 | s->tcpState = TCP_STATE::CLOSED; |
||
175 | return; |
||
176 | default: |
||
177 | break; |
||
178 | } |
||
179 | //unsigned char * p = s->rx; |
||
830 | dimkam | 180 | switch (s->MR[1]){ |
181 | case Sn_MR_TCP: |
||
182 | s->rx[0] = (len & 0xff00) >> 8; |
||
183 | s->rx[1] = len & 0x00ff; |
||
184 | s->RX_RSR = (len + 3) & 0x0001fffe; |
||
185 | break; |
||
186 | case Sn_MR_UDP: |
||
847 | DimkaM | 187 | *((ULONG*)s->rx) = r_sa_in.sin_addr.S_un.S_addr; |
188 | *((u_short*)&s->rx[4]) = r_sa_in.sin_port; |
||
830 | dimkam | 189 | s->rx[6] = (len & 0xff00) >> 8; |
190 | s->rx[7] = len & 0x00ff; |
||
191 | s->RX_RSR = (len + 9) & 0x0001fffe; |
||
192 | break; |
||
193 | case Sn_MR_IPRAW: |
||
847 | DimkaM | 194 | *((ULONG*)s->rx) = r_sa_in.sin_addr.S_un.S_addr; |
830 | dimkam | 195 | s->rx[4] = (len & 0xff00) >> 8; |
196 | s->rx[5] = len & 0x00ff; |
||
197 | s->RX_RSR = (len + 7) & 0x0001fffe; |
||
198 | break; |
||
819 | DimkaM | 199 | } |
200 | s->rx_ptr = s->rx; |
||
201 | } |
||
202 | |||
203 | READ_REG_FUNC(read_MR){ return s->MR[z]; } |
||
204 | |||
205 | READ_REG_FUNC(read_CR){ |
||
206 | if (!s->CR)return 0; |
||
207 | if (s->s == INVALID_SOCKET)return s->CR; |
||
208 | return 0; |
||
209 | } |
||
210 | |||
211 | READ_REG_FUNC(read_SSR){ |
||
212 | if (s->s == INVALID_SOCKET || s->tcpState == TCP_STATE::CLOSED) |
||
213 | return SOCK_CLOSED; |
||
214 | if (s->MR[1] == Sn_MR_TCP && s->tcpState == TCP_STATE::NONE){ |
||
215 | return SOCK_INIT; |
||
216 | } |
||
217 | FD_ZERO(&fd_s); |
||
218 | FD_SET(s->s, &fd_s); |
||
219 | iResult = select(0, NULL, NULL, &fd_s, &select_timeout); |
||
1136 | dimkam | 220 | |
221 | if (iResult == SOCKET_ERROR) return SOCK_CLOSED; |
||
222 | |||
223 | if (s->tcpState == TCP_STATE::LISTEN) |
||
224 | { |
||
819 | DimkaM | 225 | s->list = accept(s->s, (sockaddr *)&s->sa_in, &ns); |
1136 | dimkam | 226 | if ( s->list != INVALID_SOCKET ) |
227 | { |
||
819 | DimkaM | 228 | ioctlsocket(s->s, FIONBIO, &is_blocked); |
229 | closesocket(s->s); |
||
230 | s->s = s->list; |
||
231 | ioctlsocket(s->s, FIONBIO, &non_blocked); |
||
232 | bool bOptVal = true; |
||
233 | setsockopt(s->s, SOL_SOCKET, SO_KEEPALIVE, (char*)bOptVal, sizeof(bOptVal)); |
||
234 | s->tcpState = TCP_STATE::LISTEN_CONNECTED; |
||
235 | return SOCK_ESTABLISHED; |
||
236 | } |
||
237 | return SOCK_LISTEN; |
||
238 | } |
||
1136 | dimkam | 239 | |
819 | DimkaM | 240 | FD_ZERO(&fd_s); |
241 | FD_SET(s->s, &fd_s); |
||
242 | iResult = select(0, NULL, &fd_s, NULL, &select_timeout); |
||
243 | if (iResult == SOCKET_ERROR) |
||
244 | return SOCK_CLOSED; |
||
245 | if (iResult == 0){ |
||
246 | switch (s->MR[1]) |
||
247 | { |
||
248 | case Sn_MR_TCP: |
||
249 | switch (s->tcpState) |
||
250 | { |
||
251 | case TCP_STATE::LISTEN_CONNECTED: |
||
252 | case TCP_STATE::CLIENT_CONNECTED: |
||
253 | return SOCK_ESTABLISHED; |
||
254 | default: |
||
255 | FD_ZERO(&fd_s); |
||
256 | FD_SET(s->s, &fd_s); |
||
257 | iResult = select(0, NULL, NULL, &fd_s, &select_timeout); |
||
258 | if (iResult != 0){ |
||
259 | s->tcpState = TCP_STATE::CLOSED; |
||
260 | return SOCK_CLOSED; |
||
261 | } |
||
262 | return SOCK_INIT; |
||
263 | } |
||
264 | case Sn_MR_UDP: |
||
265 | return SOCK_UDP; |
||
830 | dimkam | 266 | case Sn_MR_IPRAW: |
267 | return SOCK_IPRAW; |
||
819 | DimkaM | 268 | default: |
269 | return SOCK_CLOSED; |
||
270 | } |
||
271 | } |
||
272 | else if (iResult > 0){ |
||
273 | FD_ZERO(&fd_s); |
||
274 | FD_SET(s->s, &fd_s); |
||
275 | iResult = select(0, NULL, NULL, &fd_s, &select_timeout); |
||
276 | if (iResult != 0){ |
||
277 | s->tcpState = TCP_STATE::CLOSED; |
||
278 | return SOCK_CLOSED; |
||
279 | } |
||
280 | switch (s->MR[1]) |
||
281 | { |
||
282 | case Sn_MR_TCP: |
||
283 | switch (s->tcpState) |
||
284 | { |
||
285 | case TCP_STATE::LISTEN: |
||
286 | s->tcpState = TCP_STATE::LISTEN_CONNECTED; |
||
287 | return SOCK_ESTABLISHED; |
||
288 | case TCP_STATE::CLIENT: |
||
289 | s->tcpState = TCP_STATE::CLIENT_CONNECTED; |
||
290 | return SOCK_ESTABLISHED; |
||
291 | case TCP_STATE::CLOSED: |
||
292 | return SOCK_CLOSED; |
||
293 | } |
||
294 | WizRecv(s); |
||
295 | if (s->tcpState == TCP_STATE::CLOSED) return SOCK_CLOSED; |
||
296 | return SOCK_ESTABLISHED; |
||
297 | case Sn_MR_UDP: |
||
298 | return SOCK_UDP; |
||
830 | dimkam | 299 | case Sn_MR_IPRAW: |
300 | return SOCK_IPRAW; |
||
819 | DimkaM | 301 | default: |
302 | return SOCK_CLOSED; |
||
303 | } |
||
304 | } |
||
305 | //ns = WSAGetLastError(); |
||
306 | return SOCK_CLOSED; |
||
307 | } |
||
308 | |||
309 | READ_REG_FUNC(read_PORTR){ |
||
310 | return s->PORTR[z]; |
||
311 | } |
||
312 | |||
313 | READ_REG_FUNC(read_DPORTR){ |
||
314 | if (z) return (s->sa_in.sin_port & 0xff00) >> 8; |
||
315 | else return s->sa_in.sin_port & 0x00ff; |
||
316 | } |
||
317 | |||
318 | READ_REG_FUNC(read_ZERO){ |
||
319 | return 0; |
||
320 | } |
||
321 | |||
322 | READ_REG_FUNC(read_DIPR12){ |
||
323 | if (!z) |
||
324 | return s->sa_in.sin_addr.S_un.S_un_b.s_b1; |
||
325 | else |
||
326 | return s->sa_in.sin_addr.S_un.S_un_b.s_b2; |
||
327 | } |
||
328 | |||
329 | READ_REG_FUNC(read_DIPR34){ |
||
330 | if (!z) |
||
331 | return s->sa_in.sin_addr.S_un.S_un_b.s_b3; |
||
332 | else |
||
333 | return s->sa_in.sin_addr.S_un.S_un_b.s_b4; |
||
334 | } |
||
335 | |||
830 | dimkam | 336 | READ_REG_FUNC(read_PROTOR){ |
337 | if (!z) |
||
338 | return 0x00; |
||
339 | else |
||
340 | return s->PROTOR; |
||
341 | } |
||
342 | |||
819 | DimkaM | 343 | READ_REG_FUNC(read_TX_FSR32){ |
344 | if (z == 0) return 0; |
||
1136 | dimkam | 345 | return ((sizeof(s->tx) - (s->tx_ptr - s->tx)) & 0x00010000) >> 16; |
819 | DimkaM | 346 | } |
347 | |||
348 | READ_REG_FUNC(read_TX_FSR10){ |
||
1136 | dimkam | 349 | if (z == 0) return ((sizeof(s->tx) - (s->tx_ptr - s->tx)) & 0x0000ff00) >> 8; |
1013 | lvd | 350 | return (sizeof(s->tx) - ((u_int)(s->tx_ptr - s->tx))) & 0x000000fF; |
819 | DimkaM | 351 | } |
352 | |||
353 | READ_REG_FUNC(read_RX_RSR32){ |
||
354 | if (s->s == INVALID_SOCKET)return 0; |
||
355 | if (z == 0) return 0; |
||
356 | WizRecv(s); |
||
357 | return (u_char)((s->RX_RSR & 0x00010000) >> 16); |
||
358 | } |
||
359 | |||
360 | READ_REG_FUNC(read_RX_RSR10){ |
||
361 | if (s->s == INVALID_SOCKET)return 0; |
||
362 | WizRecv(s); |
||
363 | if (z == 0) return (s->RX_RSR & 0x0000ff00) >> 8; |
||
364 | return s->RX_RSR & 0x000000fF; |
||
365 | } |
||
366 | |||
367 | READ_REG_FUNC(read_RX){ |
||
368 | if (s->RX_RSR == 0)return 0; |
||
369 | data = *(s->rx_ptr + z); |
||
370 | if (z == 0)return data; |
||
371 | s->RX_RSR -= 2; |
||
372 | if (s->RX_RSR == 0) |
||
373 | s->rx_ptr = NULL; |
||
374 | else |
||
375 | s->rx_ptr += 2; |
||
376 | return data; |
||
377 | } |
||
378 | |||
379 | u_char(*regReadFunc[0x20])(sInfoStruct *, u_char) = { |
||
380 | read_MR, read_CR, read_ZERO, read_ZERO, read_SSR, read_PORTR, read_ZERO, read_ZERO, |
||
830 | dimkam | 381 | read_ZERO, read_DPORTR, read_DIPR12, read_DIPR34, read_ZERO, read_PROTOR, read_ZERO, read_ZERO, |
819 | DimkaM | 382 | read_ZERO, read_ZERO, read_TX_FSR32, read_TX_FSR10, read_RX_RSR32, read_RX_RSR10, read_ZERO, read_ZERO, |
383 | read_RX, read_ZERO, read_ZERO, read_ZERO, read_ZERO, read_ZERO, read_ZERO, read_ZERO, |
||
384 | }; |
||
847 | DimkaM | 385 | void WIZ_CLOSE_SOC(sInfoStruct * s){ |
819 | DimkaM | 386 | if (s->s != INVALID_SOCKET){ |
387 | ioctlsocket(s->s, FIONBIO, &is_blocked); |
||
388 | iResult = closesocket(s->s); |
||
389 | DPRINTF("closesocket = %x", iResult); |
||
390 | s->s = INVALID_SOCKET; |
||
830 | dimkam | 391 | s->PROTOR = 0x00; |
819 | DimkaM | 392 | } |
393 | } |
||
394 | |||
395 | void WizOpenSocket(sInfoStruct * s){ |
||
396 | bool bOptVal = true; |
||
847 | DimkaM | 397 | DWORD tout = 3000; |
819 | DimkaM | 398 | if (s->s != INVALID_SOCKET) return; |
399 | s->RX_RSR = 0; |
||
847 | DimkaM | 400 | memset(&s->sa_in.sin_addr,0x00,sizeof(s->sa_in.sin_addr)); |
819 | DimkaM | 401 | s->sa_in.sin_family = AF_INET; |
402 | s->rx_ptr = NULL; |
||
403 | s->tx_ptr = s->tx; |
||
404 | s->tcpState = TCP_STATE::NONE; |
||
847 | DimkaM | 405 | s->BINDED = 0; |
819 | DimkaM | 406 | switch (s->MR[1]) |
407 | { |
||
408 | case Sn_MR_TCP: |
||
409 | s->s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
||
847 | DimkaM | 410 | setsockopt(s->s, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, sizeof(bOptVal)); |
819 | DimkaM | 411 | DPRINTF("Opensocket %u ", s->s); |
412 | break; |
||
413 | case Sn_MR_UDP: |
||
414 | s->s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); |
||
415 | break; |
||
830 | dimkam | 416 | case Sn_MR_IPRAW: |
847 | DimkaM | 417 | setsockopt(s->s, SOL_SOCKET, SO_RCVTIMEO, (char*)&tout, sizeof(tout)); |
830 | dimkam | 418 | s->s = socket(AF_INET, SOCK_RAW, s->PROTOR); |
419 | break; |
||
819 | DimkaM | 420 | default: |
421 | s->s = INVALID_SOCKET; |
||
422 | break; |
||
423 | } |
||
424 | if (s->s != INVALID_SOCKET){ |
||
425 | ioctlsocket(s->s, FIONBIO, &non_blocked); |
||
426 | s->CR = 0; |
||
427 | } |
||
428 | } |
||
429 | |||
430 | void WizConnect(sInfoStruct *s){ |
||
431 | if (s->MR[1] != Sn_MR_TCP || s->s == INVALID_SOCKET || s->tcpState != TCP_STATE::NONE) return; |
||
432 | s->CR = 0; |
||
433 | s->tcpState = TCP_STATE::CLIENT; |
||
434 | connect(s->s, (SOCKADDR *)&s->sa_in, sizeof(s->sa_in)); |
||
435 | } |
||
436 | |||
437 | void WisDisconnect(sInfoStruct *s){ |
||
438 | if (s->MR[1] != Sn_MR_TCP) return; |
||
439 | } |
||
440 | |||
441 | void WisListen(sInfoStruct *s){ |
||
442 | if (s->MR[1] != Sn_MR_TCP || s->s == INVALID_SOCKET || s->tcpState != TCP_STATE::NONE) return; |
||
443 | s->tcpState = TCP_STATE::LISTEN; |
||
444 | ZeroMemory(&sa_in, sizeof(sa_in)); |
||
445 | //s->list = s->s; |
||
446 | sa_in.sin_family = AF_INET; |
||
447 | sa_in.sin_addr.S_un.S_addr = 0; |
||
448 | sa_in.sin_port = (s->PORTR[1] << 8) | s->PORTR[0]; |
||
449 | bind(s->s, (sockaddr *)&sa_in, sizeof(sa_in)); |
||
847 | DimkaM | 450 | s->BINDED = 1; |
819 | DimkaM | 451 | listen(s->s, 1); |
452 | ns = sizeof(s->sa_in); |
||
453 | } |
||
454 | |||
455 | void WizSend(sInfoStruct *s){ |
||
456 | if (s->s == INVALID_SOCKET)return; |
||
457 | iResult = (int)(s->TX_WRSR.ul & 0x01ffff); |
||
458 | if (s->MR[1] == Sn_MR_TCP && s->tcpState != TCP_STATE::NONE){ |
||
459 | send(s->s, (char*)s->tx, (int)(s->TX_WRSR.ul & 0x01ffff), 0); |
||
460 | s->tx_ptr = s->tx; |
||
461 | s->TX_WRSR.ul = 0; |
||
462 | DPRINTF("Send %d bytes\r\n", iResult); |
||
463 | } |
||
830 | dimkam | 464 | else if ((s->MR[1] == Sn_MR_UDP) || (s->MR[1] == Sn_MR_IPRAW)){ |
847 | DimkaM | 465 | if(s->BINDED == 0) soc_bind(s); |
819 | DimkaM | 466 | sendto(s->s, (char*)s->tx, (int)(s->TX_WRSR.ul & 0x01ffff), 0, (sockaddr *)&s->sa_in, sizeof(sa_in)); |
467 | s->tx_ptr = s->tx; |
||
468 | s->TX_WRSR.ul = 0; |
||
469 | DPRINTF("Send %d bytes\r\n", iResult); |
||
470 | } |
||
471 | } |
||
472 | |||
473 | WRITE_REG_FUNC(write_DPORTR){ |
||
474 | if (z) s->sa_in.sin_port = ((s->sa_in.sin_port) & 0x00ff) | (d << 8); |
||
475 | else s->sa_in.sin_port = ((s->sa_in.sin_port) & 0xff00) | d; |
||
476 | }; |
||
477 | |||
478 | WRITE_REG_FUNC(write_MR){ |
||
479 | WIZ_CLOSE_SOC(s); |
||
480 | s->MR[z] = d; |
||
481 | }; |
||
482 | |||
483 | WRITE_REG_FUNC(write_CR){ |
||
484 | if (!z)return; |
||
485 | DPRINTF("Write CR = %x\r\n", d); |
||
486 | s->CR = d; |
||
487 | switch (d) |
||
488 | { |
||
489 | case Sn_CR_CLOSE: |
||
490 | WIZ_CLOSE_SOC(s); |
||
491 | s->CR = 0; |
||
492 | break; |
||
493 | case Sn_CR_RECV: |
||
494 | s->rx_ptr = NULL; |
||
495 | s->RX_RSR = 0; |
||
496 | s->CR = 0; |
||
497 | break; |
||
498 | case Sn_CR_SEND: |
||
499 | WizSend(s); |
||
500 | break; |
||
501 | case Sn_CR_DISCON: |
||
502 | if (s->s != INVALID_SOCKET){ |
||
503 | WIZ_CLOSE_SOC(s); |
||
504 | //WizOpenSocket(s); |
||
505 | s->CR = 0; |
||
506 | } |
||
507 | break; |
||
508 | case Sn_CR_OPEN: |
||
509 | WizOpenSocket(s); |
||
510 | break; |
||
511 | case Sn_CR_LISTEN: |
||
512 | WisListen(s); |
||
513 | break; |
||
514 | case Sn_CR_CONNECT: |
||
515 | WizConnect(s); |
||
516 | break; |
||
517 | default: |
||
518 | break; |
||
519 | } |
||
520 | }; |
||
521 | |||
522 | WRITE_REG_FUNC(write_PORTR){ |
||
523 | s->PORTR[z] = d; |
||
524 | }; |
||
525 | |||
526 | WRITE_REG_FUNC(write_DIPR12){ |
||
527 | if (!z)s->sa_in.sin_addr.S_un.S_un_b.s_b1 = d; |
||
528 | else s->sa_in.sin_addr.S_un.S_un_b.s_b2 = d; |
||
529 | } |
||
530 | |||
531 | WRITE_REG_FUNC(write_DIPR34){ |
||
532 | if (!z)s->sa_in.sin_addr.S_un.S_un_b.s_b3 = d; |
||
533 | else s->sa_in.sin_addr.S_un.S_un_b.s_b4 = d; |
||
534 | } |
||
535 | |||
830 | dimkam | 536 | WRITE_REG_FUNC(write_PROTOR){ |
847 | DimkaM | 537 | if (z)s->PROTOR = d; |
830 | dimkam | 538 | } |
539 | |||
819 | DimkaM | 540 | WRITE_REG_FUNC(write_TX_WRSR32){ |
541 | s->TX_WRSR.b[3 - z] = d; |
||
542 | }; |
||
543 | |||
544 | WRITE_REG_FUNC(write_TX_WRSR10){ |
||
545 | s->TX_WRSR.b[1 - z] = d; |
||
546 | }; |
||
547 | |||
548 | WRITE_REG_FUNC(write_TX){ |
||
549 | *(s->tx_ptr + z) = d; |
||
550 | if (z == 0)return; |
||
551 | s->tx_ptr += 2; |
||
552 | }; |
||
553 | |||
554 | WRITE_REG_FUNC(write_ZERO){}; |
||
555 | |||
556 | void(*regWriteFunc[0x20])(sInfoStruct * s, u_char, u_char) = { |
||
557 | write_MR, write_CR, write_ZERO, write_ZERO, write_ZERO, write_PORTR, write_ZERO, write_ZERO, |
||
830 | dimkam | 558 | write_ZERO, write_DPORTR, write_DIPR12, write_DIPR34, write_ZERO, write_PROTOR, write_ZERO, write_ZERO, |
819 | DimkaM | 559 | write_TX_WRSR32, write_TX_WRSR10, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_TX, |
560 | write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, |
||
561 | }; |
||
562 | |||
563 | u_char Wiz5300_RegRead(unsigned int Addr) |
||
564 | { |
||
565 | |||
566 | if(comp.wiznet.p82&0x08)Addr^=0x01; |
||
567 | if (Addr >= 0x0200) |
||
568 | return regReadFunc[(Addr & 0x3f) >> 1](&soc[(Addr >> 6) & 0x07], Addr & 0x01); |
||
569 | if (Addr <= 0x00ff){ |
||
570 | return regs[Addr]; |
||
571 | } |
||
572 | return 0; |
||
573 | } |
||
574 | |||
575 | void Wiz5300_RegWrite(unsigned int Addr, unsigned char Data) |
||
576 | { |
||
577 | if(comp.wiznet.p82&0x08)Addr^=0x01; |
||
578 | if (Addr >= 0x0200) |
||
579 | regWriteFunc[(Addr & 0x3f) >> 1](&soc[(Addr >> 6) & 0x07], Data, Addr & 0x01); |
||
580 | else if (Addr <= 0x00ff) { |
||
581 | regs[Addr] = stat_regs[Addr]; |
||
582 | } |
||
583 | } |
||
584 | |||
585 | void getNetProperties(void){ |
||
586 | char ac[80]; |
||
587 | gethostname(ac, sizeof(ac)); |
||
588 | struct hostent *phe = gethostbyname(ac); |
||
589 | if (phe)memcpy(&stat_regs[0x0018], phe->h_addr_list[0], 4); |
||
590 | if (*((ULONG32*)(&stat_regs[0x0018])) == 0)return; |
||
591 | |||
592 | PIP_ADAPTER_INFO pAdapterInfo, pAdapter = NULL; |
||
593 | DWORD dwRetVal = 0; |
||
594 | //unsigned int i; |
||
595 | //struct tm newtime; |
||
596 | //errno_t error; |
||
597 | ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); |
||
598 | pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO)); |
||
599 | // if (pAdapterInfo==NULL) ...return |
||
600 | if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW){ |
||
601 | free(pAdapterInfo); |
||
602 | pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen); |
||
603 | // if (pAdapterInfo==NULL) ...return |
||
604 | } |
||
605 | if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR){ |
||
606 | pAdapter = pAdapterInfo; |
||
607 | while (pAdapter) |
||
608 | { |
||
609 | if (pAdapter->IpAddressList.Context != *((DWORD32*)(&stat_regs[0x0018]))){ |
||
610 | pAdapter = pAdapter->Next; |
||
611 | continue; |
||
612 | } |
||
613 | printf("Network adapter: %s \r\n",pAdapter->Description); |
||
614 | *((ULONG32*)(&stat_regs[0x0014])) = inet_addr(pAdapter->IpAddressList.IpMask.String); |
||
615 | *((ULONG32*)(&stat_regs[0x0010])) = inet_addr(pAdapter->GatewayList.IpAddress.String); |
||
616 | memcpy(&stat_regs[0x008], pAdapter->Address, 8); |
||
617 | break; |
||
618 | } |
||
619 | } |
||
620 | else |
||
621 | { |
||
622 | //print error, no return |
||
623 | } |
||
624 | if (pAdapterInfo){ |
||
625 | free(pAdapterInfo); |
||
626 | } |
||
627 | } |
||
628 | |||
629 | int Wiz5300_Init(void) |
||
630 | { |
||
631 | ZeroMemory(stat_regs, sizeof(stat_regs)); |
||
632 | memset(&stat_regs[0x20], 0x08, 16); |
||
633 | stat_regs[0x00] = 0x38; |
||
634 | stat_regs[0xfe] = 0x53; |
||
635 | stat_regs[0x31] = 0xff; |
||
636 | memcpy(regs, stat_regs, sizeof(stat_regs)); |
||
637 | |||
638 | ZeroMemory(soc, sizeof(soc)); |
||
639 | WSAStartup(MAKEWORD(2, 2), &wsaData); |
||
640 | for (int i = 0; i < 8; i++){ |
||
641 | soc[i].s = INVALID_SOCKET; |
||
642 | soc[i].sa_in.sin_family = AF_INET; |
||
643 | soc[i].list = INVALID_SOCKET; |
||
830 | dimkam | 644 | soc[i].PROTOR = 0x00; |
819 | DimkaM | 645 | } |
646 | select_timeout.tv_sec = 0; |
||
647 | select_timeout.tv_usec = 0; |
||
648 | getNetProperties(); |
||
649 | //DPRINTF("wiz init\r\n"); |
||
650 | return 0; |
||
651 | } |
||
652 | |||
653 | int Wiz5300_Close(void) |
||
654 | { |
||
655 | for (int i = 0; i < 8; i++) { |
||
656 | if (soc[i].s != INVALID_SOCKET){ |
||
657 | ioctlsocket(soc[i].s, FIONBIO, &is_blocked); |
||
658 | closesocket(soc[i].s); |
||
659 | } |
||
660 | } |
||
661 | WSACleanup(); //Clean up Winsock |
||
662 | return 0; |
||
663 | } |
||
664 | |||
665 | |||
666 | void pXXAB_Write(unsigned port, unsigned char val){ |
||
667 | if((!(port&0x8000))&&(comp.wiznet.p82&0x10)){ |
||
668 | Wiz5300_RegWrite(((comp.wiznet.p81&0x0f)<<6)| |
||
669 | ((port&0x3f00)>>8),val); |
||
670 | return; |
||
671 | } |
||
672 | if(port==0x83ab){ |
||
673 | if((comp.wiznet.p83&0x10)^(val&0x10)){ |
||
674 | if(val&0x10){Wiz5300_Init();} |
||
675 | else {Wiz5300_Close();} |
||
676 | } |
||
677 | comp.wiznet.p83=val; |
||
678 | |||
679 | }else if(port==0x82ab){ |
||
680 | comp.wiznet.p82=val; |
||
681 | }else if(port==0x81ab){ |
||
682 | comp.wiznet.p81=val; |
||
683 | return; |
||
684 | } |
||
685 | comp.wiznet.memEna=conf.wiznet && (comp.wiznet.p82 & 0x04) |
||
686 | && (comp.wiznet.p83 & 0x10) && (!(comp.wiznet.p82 & 0x10)); |
||
687 | return; |
||
688 | } |
||
689 | |||
690 | unsigned char pXXAB_Read(unsigned port){ |
||
691 | if((!(port&0x8000))&&(comp.wiznet.p82&0x10)){ |
||
692 | return Wiz5300_RegRead(((comp.wiznet.p81&0x0f)<<6)| |
||
693 | ((port&0x3f00)>>8)); |
||
694 | |||
695 | } |
||
696 | if(port==0x83ab){ |
||
697 | return comp.wiznet.p83; |
||
698 | }else if(port==0x82ab){ |
||
699 | return comp.wiznet.p82; |
||
700 | }else if(port==0x81ab){ |
||
701 | return comp.wiznet.p81; |
||
702 | }else if(port&0x8000){return 0xFF;} |
||
703 | |||
704 | return 0xff; |
||
705 | } |
||
706 |