📄 socket.c
字号:
/*
* (c)COPYRIGHT
* ALL RIGHT RESERVED
*
* FileName : socket.c
* Revision History :
* ---------- ------- ----------- -----------------------------------------------------
* Date version Name Description
* ---------- ------- ----------- -----------------------------------------------------
* 08/28/2006 1.0.1 Bong support W3150A+
* ---------- ------- ----------- -----------------------------------------------------
* 11/10/2006 1.0.2 Jung modify interrupt part of send(), sendto(), igmpsend()
* ---------------------------------------------------------------------------------------
* 11/20/2006 1.0.3 Jung modify interrupt part of send(), sendto(), igmpsend()
* ---------------------------------------------------------------------------------------
*
* last update : Nov 20, 2006
*/
#include "socket.h"
uint16 local_port;
/**
* Internal Functions
*/
/*
*********************************************************************
This Socket function initialize the channel in perticular mode, and set the port
and wait for W3150A+ done it.
And the Parameters "s" is for socket number, "protocol" is for socket protocol,
port is the source port for the socket and flag is the option for the socket.
This function return 1 for sucess else 0.
*********************************************************************
*/
uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint8 flag)
{
uint8 ret;
if ((protocol == Sn_MR_TCP) || (protocol == Sn_MR_UDP) || (protocol == Sn_MR_IPRAW) || (protocol == Sn_MR_MACRAW) || (protocol == Sn_MR_PPPOE))
{
close(s);
IINCHIP_WRITE(Sn_MR(s),protocol | flag);
if (port != 0) {
IINCHIP_WRITE(Sn_PORT0(s),(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(port & 0x00ff));
}
else
{
local_port++; // if don't set the source port, set local_port number.
IINCHIP_WRITE(Sn_PORT0(s),(uint8)((local_port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(local_port & 0x00ff));
}
IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
ret = 1;
}
else
{
ret = 0;
}
return ret;
}
/*
*********************************************************************
This function close the socket and parameter is "s" which represent the socket number
*********************************************************************
*/
void close(SOCKET s)
{
IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
}
/*
*********************************************************************
This function established the connection for the channel in passive (server) mode.
This function waits for the request from the peer. The parameter "s" is the socket number
This function return 1 for success else 0.
*********************************************************************
*/
uint8 listen(SOCKET s)
{
uint8 ret;
if (IINCHIP_READ(Sn_SR(s)) == SOCK_INIT)
{
IINCHIP_WRITE(Sn_CR(s),Sn_CR_LISTEN);
ret = 1;
}
else
{
ret = 0;
}
return ret;
}
/*
*********************************************************************
This function established the connection for the channel in Active (client) mode.
This function waits for the untill the connection is established. The parameter "s" is the socket number
This function return 1 for success else 0.
*********************************************************************
*/
uint8 connect(SOCKET s, uint8 * addr, uint16 port)
{
uint8 ret;
if(
((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
(port == 0x00) )
{
ret = 0;
}
else
{
ret = 1;
// set destination IP
IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
IINCHIP_WRITE(Sn_CR(s),Sn_CR_CONNECT);
// wait for completion
while (IINCHIP_READ(Sn_CR(s)))
{
if (IINCHIP_READ(Sn_SR(s)) == SOCK_CLOSED)
{
ret = 0; break;
}
}
}
return ret;
}
/*
*********************************************************************
This function used for disconnect the socket and parameter is "s" which represent the socket number
*********************************************************************
*/
void disconnect(SOCKET s)
{
IINCHIP_WRITE(Sn_CR(s),Sn_CR_DISCON);
}
/*
*********************************************************************
This function used to send the data in TCP mode and the parameter "s" represents
the socket number and "buf" a pointer to data and "len" is the data size to be send.
This function return 1 for success else 0.
*********************************************************************
*/
extern unsigned int Send_meet_cnt;
uint16 send(SOCKET s, uint8 * buf, uint16 len)
{
uint8 status=0;
uint16 ret=0;
uint16 freesize=0;
if (len > getIINCHIP_TxMAX(s))
ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else
ret = len;
// if freebuf is available, start.
do
{
freesize = getSn_TX_FSR(s);
status = IINCHIP_READ(Sn_SR(s));
if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT)){ret = 0; break;}
} while (freesize < ret);
// copy data
Send_meet_cnt++;
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
while( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
{
status = IINCHIP_READ(Sn_SR(s));
if (status == SOCK_CLOSED)
{
ret = 0;
break;
}
}
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
return ret;
}
/*
*********************************************************************
This function is an application I/F function which is used to receive the data in TCP mode.
It continues to wait for data as much as the application wants to receive and the
parameter "s" represents the socket number and "buf" a pointer to copy the data
to be received and "len" is the data size to be read. This function return received data size
for success else -1.
*********************************************************************
*/
uint16 recv(SOCKET s, uint8 * buf, uint16 len)
{
uint16 ret=0;
if ( len > 0 )
{
recv_data_processing(s, buf, len);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
ret = len;
}
return ret;
}
/*
*********************************************************************
This function is an application I/F function which is used to send the data for other then
TCP mode. Unlike TCP transmission, The peer's destination address and the port is needed.
and the parameter "s" represents the socket number and "buf" a pointer to the data
and "len" is the data size to send and addr is the peer's Destination IP address and port is
the peer's destination port number. This function return send data size for success else -1.
*********************************************************************
*/
uint16 sendto(SOCKET s, uint8 * buf, uint16 len, uint8 * addr, uint16 port)
{
uint8 status=0;
uint8 isr=0;
uint16 ret=0;
if (len > getIINCHIP_TxMAX(s))
ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else
ret = len;
if(((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
((port == 0x00)) ||(ret == 0))
{
;
}
else
{
IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
// copy data
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
while( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
{
status = IINCHIP_READ(Sn_SR(s));
#ifndef __DEF_IINCHIP_INT__
isr = IINCHIP_READ(Sn_IR(s));
#endif;
if ((status == SOCK_CLOSED) || (isr & Sn_IR_TIMEOUT) || (getISR(s) & Sn_IR_TIMEOUT))
{
ret = 0; break;
}
}
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
}
return ret;
}
/*
*********************************************************************
This function is an application I/F function which is used to receive the data in other then
TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle
the header as well.
The parameter "s" represents the socket number and "buf" a pointer to copy the data to be
received and "len" is the data size to read and and addr is a pointer to store the peer's
IP address and port is a pointer to store the peer's port number.
This function return received data size for success else -1.
*********************************************************************
*/
uint16 recvfrom(SOCKET s, uint8 * buf, uint16 len, uint8 * addr, uint16 *port)
{
uint8 head[8];
uint16 data_len=0;
uint16 ptr=0;
if ( len > 0 )
{
ptr = IINCHIP_READ(Sn_RX_RD0(s));
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
switch (IINCHIP_READ(Sn_MR(s)) & 0x07)
{
case Sn_MR_UDP :
read_data(s, (uint8 *)ptr, head, 0x08);
ptr += 8;
// read peer's IP address, port number.
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
*port = head[4];
*port = (*port << 8) + head[5];
data_len = head[6];
data_len = (data_len << 8) + head[7];
read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
ptr += data_len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
break;
case Sn_MR_IPRAW :
read_data(s, (uint8 *)ptr, head, 0x06);
ptr += 6;
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
data_len = head[4];
data_len = (data_len << 8) + head[5];
read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
ptr += data_len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
break;
case Sn_MR_MACRAW :
read_data(s,(uint8*)ptr,head,2);
ptr+=2;
data_len = head[0];
data_len = (data_len<<8) + head[1] - 2;
read_data(s,(uint8*) ptr,buf,data_len);
ptr += data_len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
break;
default :
break;
}
IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
}
return data_len;
}
uint16 igmpsend(SOCKET s, uint8 * buf, uint16 len)
{
uint8 status=0;
uint8 isr=0;
uint16 ret=0;
if (len > getIINCHIP_TxMAX(s))
ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else
ret = len;
if(ret == 0)
{
}
else
{
// copy data
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
{
status = IINCHIP_READ(Sn_SR(s));
isr = IINCHIP_READ(Sn_IR(s));
if ((status == SOCK_CLOSED) || (isr & Sn_IR_TIMEOUT) || (getISR(s) & Sn_IR_TIMEOUT))
{
ret = 0;
break;
}
}
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
}
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -