Add uOLED-96-G1 C Sample Code.
[frickel.git] / projects / geeknamensschilder_c / hardware / libraries / Ethernet / utility / socket.c
blob88c81a881ed8530c1cb34f0f943d23ba4a1e653b
1 /*
3 @file socket.c
4 @brief setting chip register for socket
5 last update : 2008. Jan
7 */
9 #include "types.h"
10 #include "w5100.h"
11 #include "socket.h"
13 static uint16 local_port;
16 /**
17 @brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it.
18 @return 1 for sucess else 0.
19 */
20 uint8 socket(
21 SOCKET s, /**< for socket number */
22 uint8 protocol, /**< for socket protocol */
23 uint16 port, /**< the source port for the socket */
24 uint8 flag /**< the option for the socket */
27 uint8 ret;
28 #ifdef __DEF_IINCHIP_DBG__
29 printf("socket()\r\n");
30 #endif
31 if ((protocol == Sn_MR_TCP) || (protocol == Sn_MR_UDP) || (protocol == Sn_MR_IPRAW) || (protocol == Sn_MR_MACRAW) || (protocol == Sn_MR_PPPOE))
33 close(s);
34 IINCHIP_WRITE(Sn_MR(s),protocol | flag);
35 if (port != 0) {
36 IINCHIP_WRITE(Sn_PORT0(s),(uint8)((port & 0xff00) >> 8));
37 IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(port & 0x00ff));
38 } else {
39 local_port++; // if don't set the source port, set local_port number.
40 IINCHIP_WRITE(Sn_PORT0(s),(uint8)((local_port & 0xff00) >> 8));
41 IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(local_port & 0x00ff));
43 IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
45 /* +20071122[chungs]:wait to process the command... */
46 while( IINCHIP_READ(Sn_CR(s)) )
48 /* ------- */
49 ret = 1;
51 else
53 ret = 0;
55 #ifdef __DEF_IINCHIP_DBG__
56 printf("Sn_SR = %.2x , Protocol = %.2x\r\n", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
57 #endif
58 return ret;
62 /**
63 @brief This function close the socket and parameter is "s" which represent the socket number
64 */
65 void close(SOCKET s)
67 #ifdef __DEF_IINCHIP_DBG__
68 printf("close()\r\n");
69 #endif
71 IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
73 /* +20071122[chungs]:wait to process the command... */
74 while( IINCHIP_READ(Sn_CR(s)) )
76 /* ------- */
78 /* +2008.01 [hwkim]: clear interrupt */
79 #ifdef __DEF_IINCHIP_INT__
80 /* m2008.01 [bj] : all clear */
81 putISR(s, 0x00);
82 #else
83 /* m2008.01 [bj] : all clear */
84 IINCHIP_WRITE(Sn_IR(s), 0xFF);
85 #endif
89 /**
90 @brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer.
91 @return 1 for success else 0.
92 */
93 uint8 listen(
94 SOCKET s /**< the socket number */
97 uint8 ret;
98 #ifdef __DEF_IINCHIP_DBG__
99 printf("listen()\r\n");
100 #endif
101 if (IINCHIP_READ(Sn_SR(s)) == SOCK_INIT)
103 IINCHIP_WRITE(Sn_CR(s),Sn_CR_LISTEN);
104 /* +20071122[chungs]:wait to process the command... */
105 while( IINCHIP_READ(Sn_CR(s)) )
107 /* ------- */
108 ret = 1;
110 else
112 ret = 0;
113 #ifdef __DEF_IINCHIP_DBG__
114 printf("Fail[invalid ip,port]\r\n");
115 #endif
117 return ret;
122 @brief This function established the connection for the channel in Active (client) mode.
123 This function waits for the untill the connection is established.
125 @return 1 for success else 0.
127 uint8 connect(SOCKET s, uint8 * addr, uint16 port)
129 uint8 ret;
130 #ifdef __DEF_IINCHIP_DBG__
131 printf("connect()\r\n");
132 #endif
135 ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
136 ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
137 (port == 0x00)
140 ret = 0;
141 #ifdef __DEF_IINCHIP_DBG__
142 printf("Fail[invalid ip,port]\r\n");
143 #endif
145 else
147 ret = 1;
148 // set destination IP
149 IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
150 IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
151 IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
152 IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
153 IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
154 IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
155 IINCHIP_WRITE(Sn_CR(s),Sn_CR_CONNECT);
156 /* m2008.01 [bj] : wait for completion */
157 while ( IINCHIP_READ(Sn_CR(s)) ) ;
161 return ret;
167 @brief This function used for disconnect the socket and parameter is "s" which represent the socket number
168 @return 1 for success else 0.
170 void disconnect(SOCKET s)
172 #ifdef __DEF_IINCHIP_DBG__
173 printf("disconnect()\r\n");
174 #endif
175 IINCHIP_WRITE(Sn_CR(s),Sn_CR_DISCON);
177 /* +20071122[chungs]:wait to process the command... */
178 while( IINCHIP_READ(Sn_CR(s)) )
180 /* ------- */
185 @brief This function used to send the data in TCP mode
186 @return 1 for success else 0.
188 uint16 send(
189 SOCKET s, /**< the socket index */
190 const uint8 * buf, /**< a pointer to data */
191 uint16 len /**< the data size to be send */
194 uint8 status=0;
195 uint16 ret=0;
196 uint16 freesize=0;
197 #ifdef __DEF_IINCHIP_DBG__
198 printf("send()\r\n");
199 #endif
201 if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
202 else ret = len;
204 // if freebuf is available, start.
207 freesize = getSn_TX_FSR(s);
208 status = IINCHIP_READ(Sn_SR(s));
209 if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
211 ret = 0;
212 break;
214 #ifdef __DEF_IINCHIP_DBG__
215 printf("socket %d freesize(%d) empty or error\r\n", s, freesize);
216 #endif
217 } while (freesize < ret);
219 // copy data
220 send_data_processing(s, (uint8 *)buf, ret);
221 IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
223 /* +20071122[chungs]:wait to process the command... */
224 while( IINCHIP_READ(Sn_CR(s)) )
226 /* ------- */
228 /* +2008.01 bj */
229 #ifdef __DEF_IINCHIP_INT__
230 while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
231 #else
232 while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
233 #endif
235 /* m2008.01 [bj] : reduce code */
236 if ( IINCHIP_READ(Sn_SR(s)) == SOCK_CLOSED )
238 #ifdef __DEF_IINCHIP_DBG__
239 printf("SOCK_CLOSED.\r\n");
240 #endif
241 close(s);
242 return 0;
245 /* +2008.01 bj */
246 #ifdef __DEF_IINCHIP_INT__
247 putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
248 #else
249 IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
250 #endif
251 return ret;
256 @brief This function is an application I/F function which is used to receive the data in TCP mode.
257 It continues to wait for data as much as the application wants to receive.
259 @return received data size for success else -1.
261 uint16 recv(
262 SOCKET s, /**< socket index */
263 uint8 * buf, /**< a pointer to copy the data to be received */
264 uint16 len /**< the data size to be read */
267 uint16 ret=0;
268 #ifdef __DEF_IINCHIP_DBG__
269 printf("recv()\r\n");
270 #endif
273 if ( len > 0 )
275 recv_data_processing(s, buf, len);
276 IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
278 /* +20071122[chungs]:wait to process the command... */
279 while( IINCHIP_READ(Sn_CR(s)) )
281 /* ------- */
282 ret = len;
284 return ret;
289 @brief This function is an application I/F function which is used to send the data for other then TCP mode.
290 Unlike TCP transmission, The peer's destination address and the port is needed.
292 @return This function return send data size for success else -1.
294 uint16 sendto(
295 SOCKET s, /**< socket index */
296 const uint8 * buf, /**< a pointer to the data */
297 uint16 len, /**< the data size to send */
298 uint8 * addr, /**< the peer's Destination IP address */
299 uint16 port /**< the peer's destination port number */
302 // uint8 status=0;
303 // uint8 isr=0;
304 uint16 ret=0;
306 #ifdef __DEF_IINCHIP_DBG__
307 printf("sendto()\r\n");
308 #endif
309 if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
310 else ret = len;
314 ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
315 ((port == 0x00)) ||(ret == 0)
318 /* +2008.01 [bj] : added return value */
319 ret = 0;
320 #ifdef __DEF_IINCHIP_DBG__
321 printf("%d Fail[%.2x.%.2x.%.2x.%.2x, %.d, %d]\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
322 printf("Fail[invalid ip,port]\r\n");
323 #endif
325 else
327 IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
328 IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
329 IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
330 IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
331 IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
332 IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
334 // copy data
335 send_data_processing(s, (uint8 *)buf, ret);
336 IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
338 /* +20071122[chungs]:wait to process the command... */
339 while( IINCHIP_READ(Sn_CR(s)) )
341 /* ------- */
343 /* +2008.01 bj */
344 #ifdef __DEF_IINCHIP_INT__
345 while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
346 #else
347 while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
348 #endif
350 #ifdef __DEF_IINCHIP_INT__
351 if (getISR(s) & Sn_IR_TIMEOUT)
352 #else
353 if (IINCHIP_READ(Sn_IR(s)) & Sn_IR_TIMEOUT)
354 #endif
356 #ifdef __DEF_IINCHIP_DBG__
357 printf("send fail.\r\n");
358 #endif
359 /* +2008.01 [bj]: clear interrupt */
360 #ifdef __DEF_IINCHIP_INT__
361 putISR(s, getISR(s) & ~(Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
362 #else
363 IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
364 #endif
365 return 0;
369 /* +2008.01 bj */
370 #ifdef __DEF_IINCHIP_INT__
371 putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
372 #else
373 IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
374 #endif
377 return ret;
382 @brief This function is an application I/F function which is used to receive the data in other then
383 TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
385 @return This function return received data size for success else -1.
387 uint16 recvfrom(
388 SOCKET s, /**< the socket number */
389 uint8 * buf, /**< a pointer to copy the data to be received */
390 uint16 len, /**< the data size to read */
391 uint8 * addr, /**< a pointer to store the peer's IP address */
392 uint16 *port /**< a pointer to store the peer's port number. */
395 uint8 head[8];
396 uint16 data_len=0;
397 uint16 ptr=0;
398 #ifdef __DEF_IINCHIP_DBG__
399 printf("recvfrom()\r\n");
400 #endif
402 if ( len > 0 )
404 ptr = IINCHIP_READ(Sn_RX_RD0(s));
405 ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
406 #ifdef __DEF_IINCHIP_DBG__
407 printf("ISR_RX: rd_ptr : %.4x\r\n", ptr);
408 #endif
409 switch (IINCHIP_READ(Sn_MR(s)) & 0x07)
411 case Sn_MR_UDP :
412 read_data(s, (uint8 *)ptr, head, 0x08);
413 ptr += 8;
414 // read peer's IP address, port number.
415 addr[0] = head[0];
416 addr[1] = head[1];
417 addr[2] = head[2];
418 addr[3] = head[3];
419 *port = head[4];
420 *port = (*port << 8) + head[5];
421 data_len = head[6];
422 data_len = (data_len << 8) + head[7];
424 #ifdef __DEF_IINCHIP_DBG__
425 printf("UDP msg arrived\r\n");
426 printf("source Port : %d\r\n", *port);
427 printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
428 #endif
430 read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
431 ptr += data_len;
433 IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
434 IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
435 break;
437 case Sn_MR_IPRAW :
438 read_data(s, (uint8 *)ptr, head, 0x06);
439 ptr += 6;
441 addr[0] = head[0];
442 addr[1] = head[1];
443 addr[2] = head[2];
444 addr[3] = head[3];
445 data_len = head[4];
446 data_len = (data_len << 8) + head[5];
448 #ifdef __DEF_IINCHIP_DBG__
449 printf("IP RAW msg arrived\r\n");
450 printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
451 #endif
452 read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
453 ptr += data_len;
455 IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
456 IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
457 break;
458 case Sn_MR_MACRAW :
459 read_data(s,(uint8*)ptr,head,2);
460 ptr+=2;
461 data_len = head[0];
462 data_len = (data_len<<8) + head[1] - 2;
464 read_data(s,(uint8*) ptr,buf,data_len);
465 ptr += data_len;
466 IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
467 IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
469 #ifdef __DEF_IINCHIP_DGB__
470 printf("MAC RAW msg arrived\r\n");
471 printf("dest mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
472 printf("src mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
473 printf("type =%.2X%.2X\r\n",buf[12],buf[13]);
474 #endif
475 break;
477 default :
478 break;
480 IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
482 /* +20071122[chungs]:wait to process the command... */
483 while( IINCHIP_READ(Sn_CR(s)) )
485 /* ------- */
487 #ifdef __DEF_IINCHIP_DBG__
488 printf("recvfrom() end ..\r\n");
489 #endif
490 return data_len;
494 uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len)
496 uint8 status=0;
497 // uint8 isr=0;
498 uint16 ret=0;
500 #ifdef __DEF_IINCHIP_DBG__
501 printf("igmpsend()\r\n");
502 #endif
503 if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
504 else ret = len;
506 if (ret == 0)
509 #ifdef __DEF_IINCHIP_DBG__
510 printf("%d Fail[%d]\r\n",len);
511 #endif
513 else
515 // copy data
516 send_data_processing(s, (uint8 *)buf, ret);
517 IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
518 /* +2008.01 bj */
519 while( IINCHIP_READ(Sn_CR(s)) )
521 /* ------- */
523 /* +2008.01 bj */
524 #ifdef __DEF_IINCHIP_INT__
525 while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
526 #else
527 while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
528 #endif
530 status = IINCHIP_READ(Sn_SR(s));
531 #ifdef __DEF_IINCHIP_INT__
532 if (getISR(s) & Sn_IR_TIMEOUT)
533 #else
534 if (IINCHIP_READ(Sn_IR(s)) & Sn_IR_TIMEOUT)
535 #endif
537 #ifdef __DEF_IINCHIP_DBG__
538 printf("igmpsend fail.\r\n");
539 #endif
540 /* in case of igmp, if send fails, then socket closed */
541 /* if you want change, remove this code. */
542 close(s);
543 /* ----- */
545 return 0;
549 /* +2008.01 bj */
550 #ifdef __DEF_IINCHIP_INT__
551 putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
552 #else
553 IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
554 #endif
556 return ret;