Subversion Repositories zxusbnet

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
47 dimkam 1
#include <stdio.h>
2
#include <string.h>
3
#include "socket.h"
4
#include "w5300.h"
5
 
6
#define SWAP16(A)               ((((A << 8 ) & 0xFF00)) | ((A >> 8)& 0x00FF))
7
 
8
uint16   iinchip_source_port;
9
uint8    check_sendok_flag[MAX_SOCK_NUM];
10
 
11
uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint16 flag)
12
{
13
        IINCHIP_WRITE(Sn_MR0(s), (uint8)((protocol | flag) >> 8));
14
        IINCHIP_WRITE(Sn_MR1(s), (uint8)((protocol | flag) & 0xff));
15
        if (port != 0)
16
        {
17
                IINCHIP_WRITE(Sn_PORTR0(s),(uint8)((port & 0xff00) >> 8));
18
                IINCHIP_WRITE(Sn_PORTR1(s),(uint8)(port & 0x00ff));
19
        }
20
        else
21
        {
22
                iinchip_source_port++;     // if don't set the source port, set local_port number.
23
                IINCHIP_WRITE(Sn_PORTR0(s),(uint8)((iinchip_source_port & 0xff00) >> 8));
24
                IINCHIP_WRITE((Sn_PORTR1(s)),(uint8)(iinchip_source_port & 0x00ff));
25
        }
26
        setSn_CR(s, Sn_CR_OPEN);      // open s-th SOCKET 
27
 
28
        check_sendok_flag[s] = 1;     // initialize the sendok flag.
29
 
30
        #ifdef __DEF_IINCHIP_DBG__
31
                printf("%d : Sn_MR=0x%04x,Sn_PORTR=0x%04x(%04d),Sn_SSR=%04x\r\n",s,IINCHIP_READ(Sn_MR(s)),(uint16)((IINCHIP_READ(Sn_PORTR0(s)) << 8) + IINCHIP_READ(Sn_PORTR1(s))),(uint16)((IINCHIP_READ(Sn_PORTR0(s)) << 8) + IINCHIP_READ(Sn_PORTR1(s))),getSn_SSR(s));
32
        #endif
33
        return 1;  
34
}
35
 
36
void     close(SOCKET s)
37
{
38
        // M_08082008 : It is fixed the problem that Sn_SSR cannot be changed a undefined value to the defined value.
39
        //              Refer to Errata of W5300
40
        //Check if the transmit data is remained or not.
41
        if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getIINCHIP_TxMAX(s)) )
42
        {
43
                uint16 loop_cnt =0;
44
                while(getSn_TX_FSR(s) != getIINCHIP_TxMAX(s))
45
                {
46
                        if(loop_cnt++ > 10)
47
                        {
48
                                uint8 destip[4];
49
                                // M_11252008 : modify dest ip address
50
                                //getSIPR(destip);
51
                                destip[0] = 0;destip[1] = 0;destip[2] = 0;destip[3] = 1;
52
                                socket(s,Sn_MR_UDP,0x3000,0);
53
                                sendto(s,(uint8*)"x",1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
54
                                break; // M_11252008 : added break statement
55
                        }
56
                wait_10ms(10);
57
                }
58
        };
59
        setSn_IR(s ,0x00FF);          // Clear the remained interrupt bits.
60
        setSn_CR(s ,Sn_CR_CLOSE);     // Close s-th SOCKET     
61
}
62
 
63
 
64
uint8    connect(SOCKET s, uint8 * addr, uint16 port)
65
{
66
        if
67
        (
68
                ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
69
                ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
70
                (port == 0x00)
71
        )
72
        {
73
                #ifdef __DEF_IINCHIP_DBG__
74
                        printf("%d : Fail[invalid ip,port]\r\n",s);
75
                #endif
76
                return 0;
77
        }
78
 
79
        // set destination IP 
80
        IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
81
        IINCHIP_WRITE(Sn_DIPR1(s),addr[1]);
82
        IINCHIP_WRITE(Sn_DIPR2(s),addr[2]);
83
        IINCHIP_WRITE(Sn_DIPR3(s),addr[3]);
84
        // set destination port number
85
        IINCHIP_WRITE(Sn_DPORTR0(s),(((uint8)(port >> 8))));
86
        IINCHIP_WRITE(Sn_DPORTR1(s),(((uint8)port & 0xff)));
87
        // Connect
88
        ApplySubnet();
89
        setSn_CR(s,Sn_CR_CONNECT);
90
 
91
 
92
        while( IINCHIP_READ(Sn_SSR(s)) != SOCK_SYNSENT )
93
        {
94
                if(IINCHIP_READ(Sn_SSR(s)) == SOCK_ESTABLISHED)
95
                {
96
                        break;
97
                }
98
                if(getSn_IR(s) & Sn_IR_TIMEOUT)
99
                {
100
                        setSn_IR(s,(Sn_IR_TIMEOUT));
101
                        break;
102
                }
103
        }
104
 
105
 
106
        ClearSubnet();
107
 
108
        return 1;  
109
}
110
 
111
void     disconnect(SOCKET s)
112
{
113
        setSn_CR(s,Sn_CR_DISCON);     // Disconnect
114
}
115
 
116
uint8    listen(SOCKET s)
117
{
118
        if (getSn_SSR(s) != SOCK_INIT)
119
        {
120
                #ifdef __DEF_IINCHIP_DBG__
121
                        printf("%d : SOCKET is not created!\r\n",s);
122
                #endif
123
                return 0;
124
        }
125
        setSn_CR(s,Sn_CR_LISTEN);     // listen
126
 
127
        return 1;
128
}  
129
 
130
uint32   send(SOCKET s, uint8 * buf, uint32 len)
131
{
132
        uint8 status=0;
133
        uint32 ret=0;
134
        uint32 freesize=0;
135
        #ifdef __DEF_IINCHIP_DBG__
136
                uint32 loopcnt = 0;
137
 
138
                printf("%d : send()\r\n",s);
139
        #endif
140
 
141
        ret = len;
142
        if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
143
 
144
 
145
 
146
        /*
147
        * \note if you want to use non blocking function, <b>"do{}while(freesize < ret)"</b> code block
148
        * can be replaced with the below code. \n
149
        * \code
150
        *       while((freesize = getSn_TX_FSR(s))==0);
151
        *       ret = freesize;
152
        * \endcode
153
        */
154
        // -----------------------
155
        // NOTE : CODE BLOCK START
156
        do                                  
157
        {
158
                freesize = getSn_TX_FSR(s);
159
                status = getSn_SSR(s);
160
                #ifdef __DEF_IINCHIP_DBG__
161
                        printf("%d : freesize=%ld\r\n",s,freesize);
162
                if(loopcnt++ > 0x0010000)
163
                {
164
                        printf("%d : freesize=%ld,status=%04x\r\n",s,freesize,status);
165
                        printf("%d:Send Size=%08lx(%d)\r\n",s,ret,ret);
166
                        printf("MR=%04x\r\n",*((vuint16*)MR));
167
                        loopcnt = 0;
168
                }
169
                #endif
170
                if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT)) return 0;
171
        } while (freesize < ret);
172
        // NOTE : CODE BLOCK END
173
        // ---------------------
174
 
175
        if(ret & 0x01) wiz_write_buf(s, buf, (ret+1));
176
        else wiz_write_buf(s,buf,ret);                   // copy data
177
 
178
        #ifdef __DEF_IINCHIP_DBG__
179
                loopcnt=0;
180
        #endif   
181
 
182
        if(!check_sendok_flag[s])                 // if first send, skip.
183
        {
184
                while (!(getSn_IR(s) & Sn_IR_SENDOK))  // wait previous SEND command completion.
185
                {
186
                #ifdef __DEF_IINCHIP_DBG__
187
 
188
                if(loopcnt++ > 0x010000)
189
                {
190
                        printf("%d:Sn_SSR(%02x)\r\n",s,status);
191
                        printf("%d:Send Size=%08lx(%d)\r\n",s,ret,ret);
192
                        printf("MR=%02x%02x\r\n",*((vuint8*)MR0),*((vuint8*)MR1));
193
                        loopcnt = 0;
194
                }
195
                #endif
196
                if (getSn_SSR(s) == SOCK_CLOSED)    // check timeout or abnormal closed.
197
                {
198
                        #ifdef __DEF_IINCHIP_DBG__
199
                                printf("%d : Send Fail. SOCK_CLOSED.\r\n",s);
200
                        #endif
201
 
202
                        return 0;
203
                }
204
                }
205
                setSn_IR(s, Sn_IR_SENDOK);             // clear Sn_IR_SENDOK      
206
        }
207
        else check_sendok_flag[s] = 0;
208
 
209
        // send
210
        setSn_TX_WRSR(s,ret);  
211
        setSn_CR(s,Sn_CR_SEND);
212
 
213
        return ret;
214
}
215
 
216
uint32   recv(SOCKET s, uint8 * buf, uint32 len)
217
{
218
        uint16 pack_size=0;
219
        vint16 mr = getMR();
220
 
221
        #ifdef __DEF_IINCHIP_DBG__
222
                printf("%d : recv()\r\n",s);
223
        #endif
224
 
225
        if(IINCHIP_READ(Sn_MR0(s)) & Sn_MR_ALIGN)
226
        {
227
                wiz_read_buf(s, buf, len);
228
                setSn_CR(s,Sn_CR_RECV);
229
                return len;
230
        }
231
 
232
        wiz_read_buf(s,(uint8*)&pack_size,2);        // extract the PACKET-INFO(DATA packet length)
233
 
234
        #ifdef LITTLE_ENDIAN
235
                if(mr & MR_FS) pack_size = pack_size;
236
                else pack_size = SWAP16(pack_size);
237
        #else
238
                if(mr & MR_FS) pack_size = SWAP16(pack_size);
239
                else pack_size = pack_size;
240
        #endif
241
 
242
        #ifdef __DEF_IINCHIP_DBG__   
243
                printf("%d:pack_size=%d\r\n",s,pack_size);
244
        #endif
245
 
246
        len = pack_size;
247
        if(pack_size & 0x01) len += 1;
248
 
249
        wiz_read_buf(s, buf, len);     // copy data   
250
 
251
        setSn_CR(s,Sn_CR_RECV);                      // recv
252
 
253
   /*
254
   * \warning  send a packet for updating window size. This code block must be only used when W5300 do only receiving data.
255
   */
256
   // ------------------------
257
   // WARNING CODE BLOCK START 
258
 
259
   // M_15052008 : Replace Sn_CR_SEND with Sn_CR_SEND_KEEP.
260
   //if(!(getSn_IR(s) & Sn_IR_SENDOK))
261
   //{
262
   //   setSn_TX_WRSR(s,0);                    // size = 0
263
   //   setSn_CR(s,Sn_CR_SEND);                // send
264
   //   while(!(getSn_IR(s) & Sn_IR_SENDOK));  // wait SEND command completion
265
   //   setSn_IR(s,Sn_IR_SENDOK);              // clear Sn_IR_SENDOK bit
266
   //}
267
 
268
   // M_04072008 : Replace Sn_CR_SEND_KEEP with Sn_CR_SEND.
269
   //if(getSn_RX_RSR(s) == 0)                     // send the window-update packet when the window size is full
270
   //{
271
   //   uint8 keep_time = 0;
272
   //   if((keep_time=getSn_KPALVTR(s)) != 0x00) setSn_KPALVTR(s,0x00); // disables the auto-keep-alive-process
273
   //   setSn_CR(s,Sn_CR_SEND_KEEP);              // send a keep-alive packet by command
274
   //   setSn_KPALVTR(s,keep_time);               // restore the previous keep-alive-timer value
275
   //}
276
 
277
 
278
//   if(getSn_RX_RSR(s) == 0)                     // check if the window size is full or not
279
//   { /* Sn_RX_RSR can be compared with another value instead of ??0??,
280
//      according to the host performance of receiving data */
281
//      setSn_TX_WRSR(s,1);                       // size : 1 byte dummy size
282
//      IINCHIP_WRITE(Sn_TX_FIFOR0(s),0x00);     // write dummy data into tx memory
283
//      IINCHIP_WRITE(Sn_TX_FIFOR1(s),0x00);
284
//      setSn_CR(s,Sn_CR_SEND);                   // send                         
285
//      while(!(getSn_IR(s) & Sn_IR_SENDOK));     // wait SEND command completion 
286
//      setSn_IR(s,Sn_IR_SENDOK);                 // clear Sn_IR_SENDOK bit       
287
//   }                                                                         
288
 
289
 
290
   // WARNING CODE BLOCK END
291
   // ----------------------
292
 
293
   return (uint32)pack_size;
294
}
295
 
296
uint32   sendto(SOCKET s, uint8 * buf, uint32 len, uint8 * addr, uint16 port)
297
{
298
        uint8 status=0;
299
        uint8 isr=0;
300
        uint32 ret=0;
301
 
302
        #ifdef __DEF_IINCHIP_DBG__
303
                printf("%d : sendto():%d.%d.%d.%d(%d), len=%d\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
304
        #endif
305
 
306
        if
307
        (
308
          ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
309
          ((port == 0x00)) ||(len == 0)
310
        )
311
        {
312
                #ifdef __DEF_IINCHIP_DBG__
313
                         printf("%d : Fail[%d.%d.%d.%d, %.d, %d]\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
314
                #endif
315
                return 0;
316
        }
317
 
318
 
319
        if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
320
        else ret = len;
321
 
322
        // set destination IP address
323
        IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
324
        IINCHIP_WRITE(Sn_DIPR1(s),addr[1]);
325
        IINCHIP_WRITE(Sn_DIPR2(s),addr[2]);
326
        IINCHIP_WRITE(Sn_DIPR3(s),addr[3]);
327
        // set destination port number
328
        IINCHIP_WRITE(Sn_DPORTR0(s),((uint8)(port >> 8)));
329
        IINCHIP_WRITE(Sn_DPORTR1(s),((uint8)(port & 0xff)));
330
 
331
        wiz_write_buf(s, buf, ret+(ret & 0x01));                               // copy data
332
        // send
333
        setSn_TX_WRSR(s,ret);
334
        ApplySubnet();
335
        setSn_CR(s, Sn_CR_SEND);
336
 
337
        while (!((isr = getSn_IR(s)) & Sn_IR_SENDOK))            // wait SEND command completion
338
        {
339
                status = getSn_SSR(s);                                // warning ---------------------------------------
340
                if ((status == SOCK_CLOSED) || (isr & Sn_IR_TIMEOUT)) // Sn_IR_TIMEOUT causes the decrement of Sn_TX_FSR
341
                {                                                     // -----------------------------------------------
342
                        #ifdef __DEF_IINCHIP_DBG__
343
                                printf("%d: send fail.status=0x%02x,isr=%02x\r\n",s,status,isr);
344
                        #endif
345
                        setSn_IR(s,Sn_IR_TIMEOUT);
346
                        return 0;
347
                }
348
        }
349
 
350
        setSn_IR(s, Sn_IR_SENDOK); // Clear Sn_IR_SENDOK
351
        ClearSubnet();
352
 
353
        #ifdef __DEF_IINCHIP_DBG__           
354
                printf("%d : send()end\r\n",s);
355
        #endif       
356
 
357
        return ret;  
358
}
359
 
360
uint32   recvfrom(SOCKET s, uint8 * buf, uint32 len, uint8 * addr, uint16  *port)
361
{
362
        uint8 head[8];
363
        uint16 data_len=0;
364
        uint16 crc[2];
365
        vint16 mr = getMR();
366
 
367
        #ifdef __DEF_IINCHIP_DBG__
368
                printf("recvfrom()\r\n");
369
        #endif
370
 
371
        if ( len > 0 )
372
        {
373
 
374
                switch (IINCHIP_READ(Sn_MR1(s)) & 0x07)                 // check the mode of s-th SOCKET
375
                {                                                       // -----------------------------
376
                case Sn_MR_UDP :                                        // UDP mode 
377
 
378
                        wiz_read_buf(s, head, 8);                       // extract the PACKET-INFO
379
                        // read peer's IP address, port number.
380
 
381
                        if(mr & MR_FS)
382
                        {
383
                                addr[0] = head[1];                      // destination IP address
384
                                addr[1] = head[0];
385
                                addr[2] = head[3];
386
                                addr[3] = head[2];
387
                        }
388
                        else
389
                        {
390
                                addr[0] = head[0];
391
                                addr[1] = head[1];
392
                                addr[2] = head[2];
393
                                addr[3] = head[3];
394
                        }
395
                        #ifdef LITTLE_ENDIAN
396
                                if(mr & MR_FS)
397
                                {
398
                                        *port = head[5];                                // destination port number
399
                                        *port = (*port << 8) + head[4];
400
                                        data_len = (uint16)head[7];                     // DATA packet length
401
                                        data_len = (data_len << 8) + head[6];
402
                                }
403
                                else
404
                                {
405
                                        *port = head[4];                                // destination port number
406
                                        *port = (*port << 8) + head[5];
407
                                        data_len = (uint16)head[6];                     // DATA packet length
408
                                        data_len = (data_len << 8) + head[7];
409
                                }
410
                        #else
411
                                if(mr & MR_FS)
412
                                {
413
                                        *port = head[4];
414
                                        *port = (*port << 8) + head[5];
415
                                        data_len = (uint16)head[6];                     // DATA packet length
416
                                        data_len = (data_len << 8) + head[7];
417
                                }
418
                                else
419
                                {
420
                                        *port = head[5];
421
                                        *port = (*port << 8) + head[4];
422
                                        data_len = (uint16)head[7];                     // DATA packet length
423
                                        data_len = (data_len << 8) + head[6];
424
                                }
425
                        #endif
426
 
427
                        #ifdef __DEF_IINCHIP_DBG__
428
                                printf("UDP msg arrived:%d(0x%04x)\r\n",data_len,data_len);
429
                                printf("source Port : %d\r\n", *port);
430
                                printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
431
                        #endif
432
 
433
                        wiz_read_buf(s, buf, data_len + (data_len & 0x01) );        // data copy.
434
                        break;
435
 
436
                                                                                        // -----------------------
437
                case Sn_MR_IPRAW :                                                      // IPRAW mode
438
                        wiz_read_buf(s, (uint8*)head, 6);                               // extract the PACKET-INFO 
439
                        if((*(vint8*)MR0) & MR_FS)
440
                        {
441
                                addr[0] = head[1];                                      // destination IP address
442
                                addr[1] = head[0];
443
                                addr[2] = head[3];
444
                                addr[3] = head[2];
445
                        }
446
                        else
447
                        {
448
                                addr[0] = head[0];                                      // destination IP address
449
                                addr[1] = head[1];
450
                                addr[2] = head[2];
451
                                addr[3] = head[3];
452
                        }
453
 
454
                        #ifdef LITTLE_ENDIAN
455
                                if((*(vint8*)MR0) & MR_FS)
456
                                {
457
                                        data_len = (uint16)head[5];                      // DATA packet length
458
                                        data_len = (data_len << 8) + head[4];
459
                                }
460
                                else
461
                                {
462
                                        data_len = (uint16)head[4];                     // DATA packet length
463
                                        data_len = (data_len << 8) + head[5];
464
                                }
465
                        #else
466
                                if((*(vint8*)MR0) & MR_FS)
467
                                {
468
                                        data_len = (uint16)head[4];
469
                                        data_len = (data_len << 8) + head[5];
470
                                }
471
                                else
472
                                {
473
                                        data_len = (uint16)head[5];
474
                                        data_len = (data_len << 8) + head[4];
475
                                }
476
                        #endif
477
 
478
                        #ifndef __DEF_IINCHIP_DBG__
479
                                printf("IP RAW msg arrived\r\n");
480
                                printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
481
                        #endif
482
 
483
                        wiz_read_buf(s, buf, data_len+(data_len & 0x01));               // data copy.
484
                        break;                                
485
 
486
                                                                                        // -----------------------
487
                case Sn_MR_MACRAW :                                                     // MACRAW mode
488
                        wiz_read_buf(s,(uint8*)head,2);                                 // extract the PACKET-INFO
489
                        #ifdef LITTLE_ENDIAN
490
                                if((*(vint8*)MR0) & MR_FS)
491
                                {
492
                                        data_len = (uint16)head[1];                     // DATA packet length
493
                                        data_len = (data_len << 8) + head[0];
494
                                }
495
                                else
496
                                {
497
                                        data_len = (uint16)head[0];
498
                                        data_len = (data_len << 8) + head[1];
499
                                }
500
                        #else
501
                                if((*(vint8*)MR0) & MR_FS)
502
                                {
503
                                        data_len = (uint16)head[0];
504
                                        data_len = (data_len << 8) + head[1];
505
                                }
506
                                else
507
                                {
508
                                        data_len = (uint16)head[1];
509
                                        data_len = (data_len << 8) + head[0];
510
                                }
511
                        #endif
512
 
513
                        wiz_read_buf(s, buf, data_len + (data_len & 0x01));        // data copy.
514
                        wiz_read_buf(s,(uint8*)crc, 4);        // extract CRC data and ignore it.
515
 
516
                        break;
517
                default :
518
                        break;
519
                }
520
                setSn_CR(s,Sn_CR_RECV);                      // recv
521
        }
522
        #ifdef __DEF_IINCHIP_DBG__
523
                printf("recvfrom() end ..\r\n");
524
        #endif
525
 
526
        return data_len;  
527
}