root/branches/follower/wiz810mj/src/lib/socket.c

Revision 57, 11.9 KB (checked in by follower, 14 months ago)

DOS to Unix line-encoding conversion.

Line 
1/*
2*
3@file       socket.c
4@brief  setting chip register for socket
5*
6*/
7#include <avr/io.h>
8#include <avr/interrupt.h>
9
10#include "types.h"
11
12#ifdef __DEF_IINCHIP_DBG__
13#include <stdio.h>
14#endif
15
16
17#include "w5100.h"
18#include "socket.h"
19
20static uint16 local_port;
21
22
23/**
24@brief  This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it.
25@return     1 for sucess else 0.
26*/ 
27uint8 socket(
28    SOCKET s,       /**< for socket number */
29    uint8 protocol,     /**< for socket protocol */
30    uint16 port,        /**< the source port for the socket */
31    uint8 flag      /**< the option for the socket */
32    )
33{
34    uint8 ret;
35#ifdef __DEF_IINCHIP_DBG__
36    printf("socket()\r\n");
37#endif
38    if ((protocol == Sn_MR_TCP) || (protocol == Sn_MR_UDP) || (protocol == Sn_MR_IPRAW) || (protocol == Sn_MR_MACRAW) || (protocol == Sn_MR_PPPOE))
39    {
40        close(s);
41        IINCHIP_WRITE(Sn_MR(s),protocol | flag);
42        if (port != 0) {
43            IINCHIP_WRITE(Sn_PORT0(s),(uint8)((port & 0xff00) >> 8));
44            IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(port & 0x00ff));
45        } else {
46            local_port++; // if don't set the source port, set local_port number.
47            IINCHIP_WRITE(Sn_PORT0(s),(uint8)((local_port & 0xff00) >> 8));
48            IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(local_port & 0x00ff));
49        }
50        IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
51        ret = 1;
52    }
53    else
54    {
55        ret = 0;
56    }
57#ifdef __DEF_IINCHIP_DBG__
58    printf("Sn_SR = %.2x , Protocol = %.2x\r\n", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
59#endif
60    return ret;
61}
62
63
64/**
65@brief  This function close the socket and parameter is "s" which represent the socket number
66*/ 
67void close(SOCKET s)
68{
69#ifdef __DEF_IINCHIP_DBG__
70    printf("close()\r\n");
71#endif
72    IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
73}
74
75
76/**
77@brief  This function established  the connection for the channel in passive (server) mode. This function waits for the request from the peer.
78@return 1 for success else 0.
79*/ 
80uint8 listen(
81    SOCKET s    /**< the socket number */
82    )
83{
84    uint8 ret;
85#ifdef __DEF_IINCHIP_DBG__
86    printf("listen()\r\n");
87#endif
88    if (IINCHIP_READ(Sn_SR(s)) == SOCK_INIT)
89    {
90        IINCHIP_WRITE(Sn_CR(s),Sn_CR_LISTEN);
91        ret = 1;
92    }
93    else
94    {
95        ret = 0;
96#ifdef __DEF_IINCHIP_DBG__
97    printf("Fail[invalid ip,port]\r\n");
98#endif
99    }
100    return ret;
101}
102
103
104/**
105@brief  This function established  the connection for the channel in Active (client) mode.
106        This function waits for the untill the connection is established.
107       
108@return 1 for success else 0.
109*/ 
110uint8 connect(SOCKET s, uint8 * addr, uint16 port)
111{
112    uint8 ret;
113#ifdef __DEF_IINCHIP_DBG__
114    printf("connect()\r\n");
115#endif
116    if 
117        (
118            ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
119            ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
120            (port == 0x00) 
121        ) 
122    {
123        ret = 0;
124#ifdef __DEF_IINCHIP_DBG__
125    printf("Fail[invalid ip,port]\r\n");
126#endif
127    }
128    else
129    {
130
131        ret = 1;
132        // set destination IP
133        IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
134        IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
135        IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
136        IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
137        IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
138        IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
139        IINCHIP_WRITE(Sn_CR(s),Sn_CR_CONNECT);
140        // wait for completion
141        while (IINCHIP_READ(Sn_CR(s)))
142        {
143            if (IINCHIP_READ(Sn_SR(s)) == SOCK_CLOSED)
144            {
145#ifdef __DEF_IINCHIP_DBG__
146            printf("SOCK_CLOSED.\r\n");
147#endif
148                ret = 0; break;
149            }
150        }
151    }
152
153    return ret;
154}
155
156
157
158/**
159@brief  This function used for disconnect the socket and parameter is "s" which represent the socket number
160@return 1 for success else 0.
161*/ 
162void disconnect(SOCKET s)
163{
164#ifdef __DEF_IINCHIP_DBG__
165    printf("disconnect()\r\n");
166#endif
167    IINCHIP_WRITE(Sn_CR(s),Sn_CR_DISCON);
168}
169
170
171/**
172@brief  This function used to send the data in TCP mode
173@return 1 for success else 0.
174*/ 
175uint16 send(
176    SOCKET s,       /**< the socket index */
177    const uint8 * buf,  /**< a pointer to data */
178    uint16 len      /**< the data size to be send */
179    )
180{
181    uint8 status=0;
182    uint16 ret=0;
183    uint16 freesize=0;
184#ifdef __DEF_IINCHIP_DBG__
185    printf("send()\r\n");
186#endif
187
188   if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
189   else ret = len;
190
191   // if freebuf is available, start.
192    do 
193    {
194        freesize = getSn_TX_FSR(s);
195        status = IINCHIP_READ(Sn_SR(s));
196        if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
197        {
198            ret = 0; 
199            break;
200        }
201#ifdef __DEF_IINCHIP_DBG__
202        printf("socket %d freesize(%d) empty or error\r\n", s, freesize);
203#endif
204    } while (freesize < ret);
205
206      // copy data
207    send_data_processing(s, (uint8 *)buf, ret);
208    IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
209
210    // wait for completion
211    while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
212    {
213        status = IINCHIP_READ(Sn_SR(s));
214        if (status == SOCK_CLOSED)
215        {
216#ifdef __DEF_IINCHIP_DBG__
217            printf("SOCK_CLOSED.\r\n");
218#endif
219            putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON));
220            IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));
221            return 0;
222        }
223        }
224        putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
225    IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
226    return ret;
227}
228
229
230/**
231@brief  This function is an application I/F function which is used to receive the data in TCP mode.
232        It continues to wait for data as much as the application wants to receive.
233       
234@return received data size for success else -1.
235*/ 
236uint16 recv(
237    SOCKET s,   /**< socket index */
238    uint8 * buf,    /**< a pointer to copy the data to be received */
239    uint16 len  /**< the data size to be read */
240    )
241{
242    uint16 ret=0;
243#ifdef __DEF_IINCHIP_DBG__
244    printf("recv()\r\n");
245#endif
246
247
248    if ( len > 0 )
249    {
250        recv_data_processing(s, buf, len);
251        IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
252        ret = len;
253    }
254    return ret;
255}
256
257
258/**
259@brief  This function is an application I/F function which is used to send the data for other then TCP mode.
260        Unlike TCP transmission, The peer's destination address and the port is needed.
261       
262@return This function return send data size for success else -1.
263*/ 
264uint16 sendto(
265    SOCKET s,       /**< socket index */
266    const uint8 * buf,  /**< a pointer to the data */
267    uint16 len,         /**< the data size to send */
268    uint8 * addr,       /**< the peer's Destination IP address */
269    uint16 port     /**< the peer's destination port number */
270    )
271{
272    uint8 status=0;
273    uint8 isr=0;
274    uint16 ret=0;
275   
276#ifdef __DEF_IINCHIP_DBG__
277    printf("sendto()\r\n");
278#endif
279   if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
280   else ret = len;
281
282    if
283        (
284            ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
285            ((port == 0x00)) ||(ret == 0)
286        ) 
287    {
288       ;
289#ifdef __DEF_IINCHIP_DBG__
290    printf("%d Fail[%.2x.%.2x.%.2x.%.2x, %.d, %d]\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
291    printf("Fail[invalid ip,port]\r\n");
292#endif
293    }
294    else
295    {
296        IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
297        IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
298        IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
299        IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
300        IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
301        IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
302
303            // copy data
304            send_data_processing(s, (uint8 *)buf, ret);
305        IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
306       
307        while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
308        {
309            status = IINCHIP_READ(Sn_SR(s));
310#ifndef __DEF_IINCHIP_INT__
311            isr = IINCHIP_READ(Sn_IR(s));
312#endif
313            if ((isr & Sn_IR_TIMEOUT) || (getISR(s) & Sn_IR_TIMEOUT))
314            {
315#ifdef __DEF_IINCHIP_DBG__
316                printf("send fail.\r\n");
317#endif
318                putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON));  /* clear SEND_OK & TIMEOUT in I_STATUS[s] */
319                IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));                       // clear SEND_OK & TIMEOUT in Sn_IR(s)
320                return 0;
321            }
322        }
323        putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
324        IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
325
326    }
327    return ret;
328}
329
330
331/**
332@brief  This function is an application I/F function which is used to receive the data in other then
333    TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
334   
335@return This function return received data size for success else -1.
336*/ 
337uint16 recvfrom(
338    SOCKET s,   /**< the socket number */
339    uint8 * buf,    /**< a pointer to copy the data to be received */
340    uint16 len,     /**< the data size to read */
341    uint8 * addr,   /**< a pointer to store the peer's IP address */
342    uint16 *port    /**< a pointer to store the peer's port number. */
343    )
344{
345    uint8 head[8];
346    uint16 data_len=0;
347    uint16 ptr=0;
348#ifdef __DEF_IINCHIP_DBG__
349    printf("recvfrom()\r\n");
350#endif
351
352    if ( len > 0 )
353    {
354    ptr = IINCHIP_READ(Sn_RX_RD0(s));
355    ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
356#ifdef __DEF_IINCHIP_DBG__
357    printf("ISR_RX: rd_ptr : %.4x\r\n", ptr);
358#endif
359    switch (IINCHIP_READ(Sn_MR(s)) & 0x07)
360    {
361    case Sn_MR_UDP :
362            read_data(s, (uint8 *)ptr, head, 0x08);
363            ptr += 8;
364            // read peer's IP address, port number.
365                addr[0] = head[0];
366            addr[1] = head[1];
367            addr[2] = head[2];
368            addr[3] = head[3];
369            *port = head[4];
370            *port = (*port << 8) + head[5];
371            data_len = head[6];
372            data_len = (data_len << 8) + head[7];
373           
374#ifdef __DEF_IINCHIP_DBG__
375            printf("UDP msg arrived\r\n");
376            printf("source Port : %d\r\n", *port);
377            printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
378#endif
379
380            read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
381            ptr += data_len;
382
383            IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
384            IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
385            break;
386   
387    case Sn_MR_IPRAW :
388            read_data(s, (uint8 *)ptr, head, 0x06);
389            ptr += 6;
390   
391            addr[0] = head[0];
392            addr[1] = head[1];
393            addr[2] = head[2];
394            addr[3] = head[3];
395            data_len = head[4];
396            data_len = (data_len << 8) + head[5];
397   
398#ifdef __DEF_IINCHIP_DBG__
399            printf("IP RAW msg arrived\r\n");
400            printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
401#endif
402            read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
403            ptr += data_len;
404
405            IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
406            IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
407            break;
408    case Sn_MR_MACRAW :
409            read_data(s,(uint8*)ptr,head,2);
410            ptr+=2;
411            data_len = head[0];
412            data_len = (data_len<<8) + head[1] - 2;
413
414            read_data(s,(uint8*) ptr,buf,data_len);
415            ptr += data_len;
416            IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
417            IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
418           
419#ifdef __DEF_IINCHIP_DGB__
420            printf("MAC RAW msg arrived\r\n");
421            printf("dest mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
422            printf("src  mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
423            printf("type    =%.2X%.2X\r\n",buf[12],buf[13]); 
424#endif         
425            break;
426
427    default :
428            break;
429    }
430        IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
431    }
432#ifdef __DEF_IINCHIP_DBG__
433    printf("recvfrom() end ..\r\n");
434#endif
435    return data_len;
436}
437
438
439uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len)
440{
441    //uint8 status=0;
442    uint8 isr=0;
443    uint16 ret=0;
444   
445#ifdef __DEF_IINCHIP_DBG__
446    printf("igmpsend()\r\n");
447#endif
448   if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
449   else ret = len;
450
451    if  (ret == 0) 
452    {
453        ;
454#ifdef __DEF_IINCHIP_DBG__
455    //printf("%d Fail[%d]\r\n",len);
456#endif
457    }
458    else
459    {
460        // copy data
461        send_data_processing(s, (uint8 *)buf, ret);
462        IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
463     
464            while (IINCHIP_READ(Sn_CR(s)))
465        {
466            // status = IINCHIP_READ(Sn_SR(s));
467#ifndef __DEF_IINCHIP_INT__         
468            isr = IINCHIP_READ(Sn_IR(s));
469#endif
470            if ((getISR(s) & Sn_IR_TIMEOUT) || (isr & Sn_IR_TIMEOUT))
471            {
472#ifdef __DEF_IINCHIP_DBG__
473                printf("igmpsend fail.\r\n");
474#endif
475                putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON));
476                IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));
477                return 0;
478            }
479        }
480        putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
481        IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
482    }
483    return ret;
484}
Note: See TracBrowser for help on using the browser.