본문 바로가기

Ethernet Chat Server/1.시리얼 통신 추가

채팅 프로그램, 시리얼 통신 추가 !

이번 시간은 저번 Code에 추가적인 기능을 넣어보겠습니다.
Ethernet Socket(Client)로 부터 Data를 받았으면, 그 Data를 자신의 Socket인 Server에 Serial 출력을 하는 것과,
Server로부터 Client로 Data를 보내야하기 때문에, Serial Data를 읽어서 Client로 보내는 것까지의 Code 구현을 해보겠습니다.

[code language="c"]
/*
===============================================================================
Name : W5500-EVB.c
Author : $(author)
Version :
Copyright : $(copyright)
Description : main definition
===============================================================================
*/

#if defined (__USE_LPCOPEN)
#if defined(NO_BOARD_LIB)
#include <chip.h>
#else
#include <board.h>
#endif
#endif

#include "cr_section_macros.h"
#include "socket.h"
#include "spi_handler.h"
#include "w5500_init.h""

// TODO: insert other include files here

// TODO: insert other definitions and declarations here
#define SOCK_TCPS0 0
#define DATA_BUF_SIZE 2048
#define UART_BUF_SIZE 2048
uint8_t gDATABUF[DATA_BUF_SIZE];
uint8_t uDATABUF[UART_BUF_SIZE];
/* for문을 사용하여 Ethernet Data를 Serial Data로 출력 */
int EtherToSerial(uint8_t* buf, uint16_t size) // Client로부터 Data Read
{
	uint8_t i;
	for (i = 0; i < size; i++){
		putchar(buf[i]);
	}
	return 0;
}

int SerialToEther(uint8_t sn) // 폴링으로 Serial(UART)Data 읽어서 Client로 송신
{
	uint8_t serial_rx_data;
	//uint16_t size=0;

	if ((Chip_UART_ReadLineStatus(LPC_USART) & UART_LSR_RDR) == 1){ // UART Data를 읽으면
		Chip_UART_Read(LPC_USART, &serial_rx_data, 1); // UART Data를 읽어서

		send(sn, &serial_rx_data, 1); // DATA를 송신

	}
	return 0;
}


int main(void) {

	uint8_t ip[4] = { 192, 168, 0, 45 };
	uint16_t port = 23;
	uint8_t sn = SOCK_TCPS0;
	uint16_t size = 0;

#if defined (__USE_LPCOPEN)
#if !defined(NO_BOARD_LIB)
	// Read clock settings and update SystemCoreClock variable
	SystemCoreClockUpdate();
	// Set up and initialize all required blocks and
	// functions related to the board hardware
	Board_Init();
	// Set the LED to the state of &quot;On&quot;
	Board_LED_Set(0, true);
#endif
#endif
	SPI_Init();
	W5500_Init();
	Net_Conf();

	//Socket Creation
	if (socket(sn, Sn_MR_TCP, port, 0x00) == sn){ // 소켓 생성
		printf("%d:Socket Opened\r\n", sn);
	}
	else{
		printf("%d:Socket Error\r\n", sn);
		while (1);
	}

	//printf("%d:Connecting, ip[%d.%d.%d.%d] port [%d]\r\n", sn, ip[0], ip[1], ip[2], ip[3], port);
	/*
	if(connect(sn,ip,port)==SOCK_OK);
	else {
	printf("%d:Connect Error\r\n",sn);
	while(1);
	}
	*/
	if (listen(sn) == SOCK_OK); { // Server니깐 listen 상태 돌입
		printf("%d:listen OK\r\n", sn);
	}
	else{
		printf("%d:listen Error\r\n", sn);
		while (1);
	}


	while (1) {
		switch (getSn_SR(sn)) { // sn의 상태를 읽음.
		case SOCK_CLOSED:
			/* Socket Closed State */

			break;
		case SOCK_INIT:
			/* TCP Socket Creatation */

			break;
		case SOCK_LISTEN:
			/* TCP Server Mode */

			break;
		case SOCK_ESTABLISHED: // Client와 연결이 되면 Sn_IR_CON이 1번 출력
			/* TCP ESTABLISHED */
			//Connect Interrupt Check
			if (getSn_IR(sn) & Sn_IR_CON) { // socket = 0 -&gt; Sn_IR_CON = 0x01 -&gt; 0 is interrupt
				printf("%d:Connected\r\n", sn);
				setSn_IR(sn, Sn_IR_CON); // again IMR bit set.
				Board_LED_Set(0, false);
				Board_LED_Set(1, true);
			}
			//Receive Data Check
			if ((size = getSn_RX_RSR(sn)) > 0) {
				if (size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
				recv(sn, gDATABUF, size); // Ethernet Data read
				EtherToSerial(gDATABUF, size); // Serial Data로 Server에 출력
			}
			SerialToEther(sn); // 폴링으로 계속 돌고있음.
			break;

		case SOCK_CLOSE_WAIT:
			/* Disconnect request */

			break;
		}
	}
	return 0;
}
[/code]

하지만, 위의 코드에서의 문제점은..아래와 같아요..

- Client로 Data를 송신할때 1byte 밖에 통신이 안된다는 점인데요, 즉, 채팅 시 Data가 한번에 전송이 안된다는 것이다. 그래서 Data가 한번에 전송되는 Code를 구현해야 합니다.

보완할 것은..

1. Data 한번에 전송되게 하기
2. Socket, listen을 Switch문 안에 넣어 구현하는 것을 생각해보자.
3. UART Data를 interrupt로 받아 처리하기.