📄 socket.c
字号:
/**
* \file socket.c
* Implemetation of WIZnet SOCKET API fucntions
*
* This file implements the WIZnet SOCKET API functions that is used in your internat application program.
*
* Revision History :
* ---------- ------- ----------- ----------------------------
* Date Version Author Description
* ---------- ------- ----------- ----------------------------
* 24/03/2008 1.0.0 MidnightCow Release with W5300 launching
* ---------- ------- ----------- ----------------------------
* 15/05/2008 1.1.0 MidnightCow Refer to M_15052008.
* Modify the warning code block in recv().
* ---------- ------- ----------- ----------------------------
* 04/07/2008 1.1.1 MidnightCow Refer to M_04072008.
* Modify the warning code block in recv().
* ---------- ------- ----------- ----------------------------
* 08/08/2008 1.2.0 MidnightCow Refer to M_08082008.
* Modify close().
* ---------- ------- ----------- ----------------------------
* 11/25/2008 1.2.1 Bongjun Refer to M_11252008.
* Modify close().
* ---------- ------- ----------- ----------------------------
*/
#include "socket.h"
#include "lstring.h"
#include "string.h"
/**
* Variable for temporary source port number
*/
uint16 iinchip_source_port;
/**
* The flag to check if first send or not.
*/
uint8 check_sendok_flag[MAX_SOCK_NUM];
uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint16 flag)
{
IINCHIP_WRITE(Sn_MR(s),(uint16)(protocol | flag)); // set Sn_MR with protocol & flag
if (port != 0) IINCHIP_WRITE(Sn_PORTR(s),port);
else
{
iinchip_source_port++; // if don't set the source port, set local_port number.
IINCHIP_WRITE(Sn_PORTR(s),iinchip_source_port);
}
setSn_CR(s, Sn_CR_OPEN); // open s-th SOCKET
check_sendok_flag[s] = 1; // initialize the sendok flag.
#ifdef __DEF_IINCHIP_DBG__
printf("%d : Sn_MR=0x%04x,Sn_PORTR=0x%04x(%d),Sn_SSR=%04x\r\n",s,IINCHIP_READ(Sn_MR(s)),IINCHIP_READ(Sn_PORTR(s)),IINCHIP_READ(Sn_PORTR(s)),getSn_SSR(s));
#endif
return 1;
}
void close(SOCKET s)
{
// M_08082008 : It is fixed the problem that Sn_SSR cannot be changed a undefined value to the defined value.
// Refer to Errata of W5300
//Check if the transmit data is remained or not.
if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getIINCHIP_TxMAX(s)) )
{
uint16 loop_cnt =0;
while(getSn_TX_FSR(s) != getIINCHIP_TxMAX(s))
{
if(loop_cnt++ > 10)
{
uint8 destip[4];
// M_11252008 : modify dest ip address
//getSIPR(destip);
destip[0] = 0;destip[1] = 0;destip[2] = 0;destip[3] = 1;
socket(s,Sn_MR_UDP,0x3000,0);
sendto(s,(uint8*)"x",1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
break; // M_11252008 : added break statement
}
wait_10ms(10);
}
};
////////////////////////////////
setSn_IR(s ,0x00FF); // Clear the remained interrupt bits.
setSn_CR(s ,Sn_CR_CLOSE); // Close s-th SOCKET
}
uint8 connect(SOCKET s, uint8 * addr, uint16 port)
{
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)
)
{
#ifdef __DEF_IINCHIP_DBG__
printf("%d : Fail[invalid ip,port]\r\n",s);
#endif
return 0;
}
// set destination IP
IINCHIP_WRITE(Sn_DIPR(s),((uint16)addr[0]<<8)+(uint16)addr[1]);
IINCHIP_WRITE(Sn_DIPR2(s),((uint16)addr[2]<<8)+(uint16)addr[3]);
// set destination port number
IINCHIP_WRITE(Sn_DPORTR(s),port);
// Connect
setSn_CR(s,Sn_CR_CONNECT);
return 1;
}
void disconnect(SOCKET s)
{
setSn_CR(s,Sn_CR_DISCON); // Disconnect
}
uint8 listen(SOCKET s)
{
if (getSn_SSR(s) != SOCK_INIT)
{
#ifdef __DEF_IINCHIP_DBG__
printf("%d : SOCKET is not created!\r\n",s);
#endif
return 0;
}
setSn_CR(s,Sn_CR_LISTEN); // listen
return 1;
}
uint32 send(SOCKET s, uint8 * buf, uint32 len)
{
uint8 status=0;
uint32 ret=0;
uint32 freesize=0;
#ifdef __DEF_IINCHIP_DBG__
uint32 loopcnt = 0;
printf("%d : send()\r\n",s);
#endif
ret = len;
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
/*
* \note if you want to use non blocking function, <b>"do{}while(freesize < ret)"</b> code block
* can be replaced with the below code. \n
* \code
* while((freesize = getSn_TX_FSR(s))==0);
* ret = freesize;
* \endcode
*/
// -----------------------
// NOTE : CODE BLOCK START
do
{
freesize = getSn_TX_FSR(s);
status = getSn_SSR(s);
#ifdef __DEF_IINCHIP_DBG__
printf("%d : freesize=%ld\r\n",s,freesize);
if(loopcnt++ > 0x0010000)
{
printf("%d : freesize=%ld,status=%04x\r\n",s,freesize,status);
printf("%d:Send Size=%08lx(%d)\r\n",s,ret,ret);
printf("MR=%04x\r\n",*((vuint16*)MR));
loopcnt = 0;
}
#endif
if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT)) return 0;
} while (freesize < ret);
// NOTE : CODE BLOCK END
// ---------------------
wiz_write_buf(s,buf,ret); // copy data
#ifdef __DEF_IINCHIP_DBG__
loopcnt=0;
#endif
if(!check_sendok_flag[s]) // if first send, skip.
{
while (!(getSn_IR(s) & Sn_IR_SENDOK)) // wait previous SEND command completion.
{
#ifdef __DEF_IINCHIP_DBG__
if(loopcnt++ > 0x010000)
{
printf("%d:Sn_SSR(%04x)\r\n",s,status);
printf("%d:Send Size=%08lx(%d)\r\n",s,ret,ret);
printf("MR=%04x\r\n",*((vuint16*)MR));
loopcnt = 0;
}
#endif
if (getSn_SSR(s) == SOCK_CLOSED) // check timeout or abnormal closed.
{
#ifdef __DEF_IINCHIP_DBG__
printf("%d : Send Fail. SOCK_CLOSED.\r\n",s);
#endif
return 0;
}
}
setSn_IR(s, Sn_IR_SENDOK); // clear Sn_IR_SENDOK
}
else check_sendok_flag[s] = 0;
// send
setSn_TX_WRSR(s,ret);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -