socket.c

来自「W3100A网络调试程序,可进行数据传输」· C语言 代码 · 共 876 行 · 第 1/2 页

C
876
字号
	return ret;
}
#endif	// __TCP__


/*---------------*/
#ifdef	__UDP__
/**
* return 
*		n => count of sending data
*/
unsigned int sendto(unsigned char s, const unsigned char * buf, unsigned int len, unsigned char * addr, unsigned int port)
{
	unsigned int ret;
	if
		(
		 	((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
		 	(port == 0x00) 
		) 
 	{
 		ret = 0;
	}
	else
	{
		// 1. write destination IP
		IINCHIP_WRITE(DST_IP_PTR(s),addr[0]);
		IINCHIP_WRITE((DST_IP_PTR(s) + 1),addr[1]);
		IINCHIP_WRITE((DST_IP_PTR(s) + 2),addr[2]);
		IINCHIP_WRITE((DST_IP_PTR(s) + 3),addr[3]);
		// 2. write destination Port number
#ifndef _LITTLE_ENDIAN_
		IINCHIP_WRITE(DST_PORT_PTR(s),(unsigned char)((port & 0xff00) >> 8));
		IINCHIP_WRITE((DST_PORT_PTR(s) + 1),(unsigned char)(port & 0x00ff));
#else
		IINCHIP_WRITE((DST_PORT_PTR(s)+1),(unsigned char)((port & 0xff00) >> 8));
		IINCHIP_WRITE(DST_PORT_PTR(s),(unsigned char)(port & 0x00ff));
#endif
		// 3. call send_in func
		ret = send_in(s, buf, len, 0x00);
	}
	return ret;
}

/**
* return 
* 		n => count of receiving data
* attention
*		UDP牢 版快 茄 菩哦 窜困肺 贸府窍霸 等促.
* 		溜, len沥焊俊 1000阑 利菌歹扼档, 茄菩哦捞 500捞搁 500阑 府畔窍绊 辆丰茄促.
*/
unsigned int recvfrom(unsigned char s, const unsigned char * buf, unsigned int len, unsigned char * addr, unsigned int * port)
{
	unsigned char xdata head[8];
	unsigned int data_len;
	unsigned int rd_ptr;
	unsigned char * recv_ptr;

	data_len = 0;

#ifndef _LITTLE_ENDIAN_
	rd_ptr = IINCHIP_READ(RX_RD_PTR(s));
	rd_ptr = ((rd_ptr & 0x00ff) << 8) + IINCHIP_READ(RX_RD_PTR(s) + 1);
#else
	rd_ptr = IINCHIP_READ(RX_RD_PTR(s)+1);
	rd_ptr = ((rd_ptr & 0x00ff) << 8) + IINCHIP_READ(RX_RD_PTR(s));
#endif
	recv_ptr = (unsigned char *)(rd_ptr);
		
	switch (IINCHIP_READ(OPT_PROTOCOL(s)) & 0x07)
	{
	case SOCK_DGRAM :
			read_data(s, recv_ptr, head, 0x08);
			// 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];
			rd_ptr = rd_ptr + data_len + 8;
			recv_ptr += 8;
			break;

	case SOCK_IPL_RAWM :
			read_data(s, recv_ptr, head, 0x06);		// read header.
			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];
			rd_ptr = rd_ptr + data_len + 6;
			recv_ptr += 6;
			break;

	default :
			printf("No support protocol in recvfrom()\r\n");
			return 0;
			break;
	}

	if (data_len > len) data_len = len;
	read_data(s, recv_ptr, buf, data_len); // read data
#ifndef _LITTLE_ENDIAN_
	IINCHIP_WRITE(RX_RD_PTR(s),(unsigned char)((rd_ptr & 0xff00) >> 8));
	IINCHIP_WRITE((RX_RD_PTR(s) + 1),(unsigned char)(rd_ptr & 0x00ff));
#else
	IINCHIP_WRITE((RX_RD_PTR(s)+1),(unsigned char)((rd_ptr & 0xff00) >> 8));
	IINCHIP_WRITE(RX_RD_PTR(s),(unsigned char)(rd_ptr & 0x00ff));
#endif
	IINCHIP_WRITE(COMMAND(s),CRECV);
	return data_len;
}
#endif	// __UDP__

unsigned int read_data(unsigned char s, unsigned char * src, unsigned char * dst, unsigned int len)
{
	unsigned int size;
	unsigned int src_mask;
	unsigned char xdata * src_ptr;

	if (len == 0) return (0);

	src_mask = (unsigned int)src & RMASK[s];
	src_ptr = (RBUFBASEADDRESS[s] + src_mask);
	
	if( (src_mask + len) > RSIZE[s] ) 
	{
		size = RSIZE[s] - src_mask;
		memcpy(dst, src_ptr, size);
		dst += size;
		size = len - size;
		src_ptr = (unsigned char *)(RBUFBASEADDRESS[s]);
		memcpy(dst, src_ptr, size);
	} else
	{
		memcpy(dst, src_ptr, len);
	}

	return (len);
}

unsigned int send_in(unsigned char s, const unsigned char *buf, unsigned int len, unsigned char kind)
{
	unsigned int ret;
	unsigned int freesize;
	unsigned int wr_ptr;

S_START:

#ifndef _LITTLE_ENDIAN_
	freesize = IINCHIP_READ(TX_FREE_SIZE_PTR(s));
	freesize = ((freesize & 0x00ff) << 8) + IINCHIP_READ(TX_FREE_SIZE_PTR(s)+1);
#else
	freesize = IINCHIP_READ(TX_FREE_SIZE_PTR(s) + 1);
	freesize = ((freesize & 0x00ff) << 8) + IINCHIP_READ(TX_FREE_SIZE_PTR(s));
#endif

	if ((freesize > SSIZE[s]) || (freesize == 0))
	{
		if ((IINCHIP_READ(SOCK_STATUS(s)) != SOCK_ESTABLISHED) && (IINCHIP_READ(SOCK_STATUS(s)) != SOCK_CLOSE_WAIT)) return 0;
		goto S_START;
	}
	else
	{
 		if (freesize < len) ret = freesize;
 		else ret = len;

#ifndef _LITTLE_ENDIAN_
		wr_ptr = IINCHIP_READ(TX_WR_PTR(s));
		wr_ptr = ((wr_ptr & 0x00ff) << 8) + IINCHIP_READ(TX_WR_PTR(s) + 1);
#else
		wr_ptr = IINCHIP_READ(TX_WR_PTR(s)+1);
		wr_ptr = ((wr_ptr & 0x00ff) << 8) + IINCHIP_READ(TX_WR_PTR(s));
#endif
		
#ifdef _DEBUG
		printf("prev wr_ptr : %.4x ",wr_ptr);
#endif
		write_data(s, (unsigned char *)buf, (unsigned char *)wr_ptr, ret);		// copy data
		wr_ptr += ret;		//  update tx_wr_ptr
#ifdef _DEBUG
		printf("post wr_ptr : %.4x ",wr_ptr);
#endif

#ifndef _LITTLE_ENDIAN_
		IINCHIP_WRITE(TX_WR_PTR(s),(unsigned char)((wr_ptr & 0xff00) >> 8));
		IINCHIP_WRITE((TX_WR_PTR(s) + 1),(unsigned char)(wr_ptr & 0x00ff));
#else
		IINCHIP_WRITE((TX_WR_PTR(s) + 1),(unsigned char)((wr_ptr & 0xff00) >> 8));
		IINCHIP_WRITE(TX_WR_PTR(s),(unsigned char)(wr_ptr & 0x00ff));
#endif

		if (kind == 0x01) IINCHIP_WRITE(COMMAND(s),CSENDMAC);
		else  IINCHIP_WRITE(COMMAND(s),CSEND);
		
		while (IINCHIP_READ(COMMAND(s)))
		{
			if ((IINCHIP_READ(INT_STATUS(s)) & ISR_TIMEOUT ) || (IINCHIP_READ(SOCK_STATUS(s)) == SOCK_CLOSED))
			{
				printf("Socket %bd closed in sending function.\r\n", s);
				return 0;
			}
		}
	}
	return ret;
}

unsigned int write_data(unsigned char s, unsigned char * src, unsigned char * dst, unsigned int len)
{
	unsigned int size;
	unsigned int dst_mask;
	unsigned char xdata * dst_ptr;

	if (len == 0) return (0);

	dst_mask = (unsigned int)dst & SMASK[s];
	dst_ptr = (SBUFBASEADDRESS[s] + dst_mask);
	
	if (dst_mask + len > SSIZE[s]) 
	{
		size = SSIZE[s] - dst_mask;
		memcpy(dst_ptr, src, size);

		src += size;
		size = len - size;
		dst_ptr = (SBUFBASEADDRESS[s]);
		memcpy(dst_ptr, src, size);
	} else
	{
		//for (i = 0; i< len; i++) PutHTOA(src[i]);
		//PutLTOA(len);
		memcpy(dst_ptr, src, len);
	}
	return (len);
}

#ifdef _DEF_IINCHIP_PPP
/*
* make PPPoE connection
*/
unsigned char pppinit(unsigned char * id, unsigned char idlen, unsigned char * passwd, unsigned char passwdlen)
{
	unsigned int ii;
	unsigned char isr = 0;
	unsigned int wr_ptr;
	unsigned char * send_ptr;
	unsigned char xdata buf[1];

	// enable pppoe mode
	IINCHIP_WRITE(TMODE,IINCHIP_READ(TMODE) | TMODE_PPPOE);

	// open socket in pppoe mode
	isr = IINCHIP_READ(INT_STATUS(0));
	IINCHIP_WRITE(OPT_PROTOCOL(0),SOCK_PPPOEM);
	IINCHIP_WRITE(COMMAND(0),CSOCKINIT);
	wait_1us(1);

	// start to connect pppoe connection
	printf("1. Get PPPoE server information ");
	IINCHIP_WRITE(COMMAND(0),CCONNECT);
	
	ii = 0;
	// wait an authentication stage.
	while (1)
	{
		isr = IINCHIP_READ(INT_STATUS(0));
		// Ready to PPP Auth
		if (isr & ISR_RECV) break;
		ii++;printf(".");
		wait_10ms(50);
		if (ii==10)
		{
			printf("timeout\r\n");
			return 3;
		}
	}
	printf("\r\n");
	printf("2. Enter PPPoE Authentication mode : ");
//	PutByte(id[0]);PutHTOA(idlen);PutByte(passwd[0]);PutHTOA(passwdlen);

	// pap mode
	if (IINCHIP_READ(PPPAUTH) == 0xc0 && IINCHIP_READ(PPPAUTH+1) == 0x23)
	{
		printf("PAP");
#ifndef _LITTLE_ENDIAN_
		wr_ptr = IINCHIP_READ(TX_WR_PTR(0));
		wr_ptr = ((wr_ptr & 0x00ff) << 8) + IINCHIP_READ(TX_WR_PTR(0) + 1);
#else
		wr_ptr = IINCHIP_READ(TX_WR_PTR(0)+1);
		wr_ptr = ((wr_ptr & 0x00ff) << 8) + IINCHIP_READ(TX_WR_PTR(0));
#endif
		// copy (idlen + id + passwdlen + passwd)
		send_ptr = (unsigned char *)(wr_ptr);
		buf[0] = idlen;
		write_data(0, buf, send_ptr, 0x01);
		send_ptr++;
		write_data(0, id, send_ptr, idlen);
		send_ptr += idlen;
		buf[0] = passwdlen;
		write_data(0, buf, send_ptr, 0x01);
		send_ptr++;
		write_data(0, passwd, send_ptr, passwdlen);
		
		wr_ptr = wr_ptr + idlen + passwdlen + 2;
#ifndef _LITTLE_ENDIAN_
		IINCHIP_WRITE(TX_WR_PTR(0),(unsigned char)((wr_ptr & 0xff00) >> 8));
		IINCHIP_WRITE((TX_WR_PTR(0) + 1),(unsigned char)(wr_ptr & 0x00ff));
#else
		IINCHIP_WRITE((TX_WR_PTR(0)+1),(unsigned char)((wr_ptr & 0xff00) >> 8));
		IINCHIP_WRITE(TX_WR_PTR(0),(unsigned char)(wr_ptr & 0x00ff));
#endif
	}
	else
	{
		printf("Not support\r\n");
#ifdef _DEF_DRIVER_DBG
//		printf("Not support PPP Auth type: %.2x%.2x\r\n",IINCHIP_READ(PPPAUTH), IINCHIP_READ(PPPAUTH+1));
#endif
		return 4;
	}

	printf("\r\n");
	printf("3. Wait PPPoE server's admission ");
	// send authentication data
	IINCHIP_WRITE(COMMAND(0),CSEND);

	ii = 0;
	// wait a connection stage
	while (1)
	{
		isr = IINCHIP_READ(INT_STATUS(0));
		// success to connect
		if (isr & ISR_CON)
		{
			printf("ok");
			break;
		}
		if (isr & ISR_TIMEOUT)
		{
			printf("failed\r\nReinput id, password..\r\n");
			return 2;
		}
		ii++;printf(".");
		wait_10ms(50);
		if (ii==10) 
		{
#ifdef _DEF_DRIVER_DBG
			//printf("PPP timeout after LCP: %.2x\r\n",IINCHIP_READ(SOCK_STATUS(0)));
#endif
			printf("timeout\r\n");
			return 3;
		}
	}

	printf("\r\n");
	// close socket
	IINCHIP_WRITE(COMMAND(0),CCLOSE);
	return 1;
	// after this function, User must save the pppoe server's mac address and pppoe session id in current connection
}

/*
* terminate PPPoE connection
*/
unsigned char pppterm(unsigned char * mac, unsigned int sessionid)
{
	unsigned int i;
	unsigned char isr;
#ifdef _DEF_DRIVER_DBG
	printf("pppterm()\r\n");
#endif
	// enable pppoe mode
	IINCHIP_WRITE(TMODE,IINCHIP_READ(TMODE) | TMODE_PPPOE);
	
	// write pppoe server's mac address and session id 
	// must be setted these value.
	for (i = 0; i < 6; i++) IINCHIP_WRITE((DST_HA_PTR(0)+i),mac[i]);
#ifndef _LITTLE_ENDIAN_
		IINCHIP_WRITE(DST_PORT_PTR(0),(unsigned char)((sessionid & 0xff00) >> 8));
		IINCHIP_WRITE((DST_PORT_PTR(0) + 1),(unsigned char)(sessionid & 0x00ff));
#else
		IINCHIP_WRITE((DST_PORT_PTR(0)+1),(unsigned char)((sessionid & 0xff00) >> 8));
		IINCHIP_WRITE(DST_PORT_PTR(0),(unsigned char)(sessionid & 0x00ff));
#endif
	isr = IINCHIP_READ(INT_STATUS(0));
	
	//open socket in pppoe mode
	IINCHIP_WRITE(OPT_PROTOCOL(0),SOCK_PPPOEM);
	IINCHIP_WRITE(COMMAND(0),CSOCKINIT);
	wait_1us(1);
	// close pppoe connection
	IINCHIP_WRITE(COMMAND(0),CDISCONNECT);
	wait_10ms(100);
	// close socket
	IINCHIP_WRITE(COMMAND(0),CCLOSE);

#ifdef _DEF_DRIVER_DBG
	printf("pppterm() end ..\r\n");
#endif

	return 1;
}

void wait_10ms(int cnt)
{
	unsigned int i;

	for (i = 0; i < cnt; i++) wait_1ms(10);
}
void wait_1ms(int cnt)
{
	unsigned int i;

	for (i = 0; i < cnt; i++) wait_1us(1000);
}
#endif


/*
********************************************************************************
*               Designate the delay
*
* Description : Wait for 1 microsecond
* Arguments   : cnt - time to wait
* Returns     : None
* Note        : Internal Function, System Dependant            
********************************************************************************
*/
void wait_1us(int cnt)
{
	unsigned int i;

	for (i = 0; i < cnt; i++) ;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?