WIZnet Developer Forum

MAC_RAW Socket 모드 동작에 대하여 문의드립니다

현재 Wiz750SR을 이용하여 ethernet to uart(Wiz750SR) -> uart to PLC(Qualcomm PLC Chip)와 같은 형태로,
Ethernet to PLC(전력선통신) 변환 모듈을 Wiz750SR MCU를 이용하여 구현중에 있습니다.
전체구조상 Wiznet 모듈은 TCP or UDP 동작을 하면 안되고, MAC_RAW모드로 그대로 패킷을 양방향으로 통과시키도록 소스를 수정하고 있습니다.

일단 Wiznet구동후 첫번째 수신하는 패킷은 잘 받아오는 것을 확인하였습니다.
즉, PacketLength(2byte) + PacketData 형태로 S0_RX_RD(버퍼 포인터)와 S0RX_RSR(수신 데이터 length) Register가 잘 동작하는 것을 확인하였습니다.
그러나, 정상적인 패킷 수신직후 do_seg()루틴을 다시 거치게 되면 S0_RX_RSR의 값이 65534으로 비정상적인 값을 읽어오면서, S0소켓을 close 및
초기화하기 전까지 S0소켓은 더이상 동작하지 않습니다.

이와함께 MAC_RAW 모드로 패킷을 보낼 경우, 송신 데이터 구조를 알고 싶습니다.
소스상 ethernet으로부터 수신받는 경우는 앞 2바이트에 패킷길이가 추가되는 것을 보았습니다.
MAC_RAW 모드로 패킷을 ethernet으로 보내는 경우도 앞쪽 2바이트에 보내고자하는 패킷의 길이를 명시해 해주어 하는지요?
RAW Packet을 그대로 송부할 경우는 일단 Wireshark로는 검출하지 못 하는 것을 확인하였습니다.
(물론 전송하는 패킷데이터가 올바르다고 보장할 수 는 없습니다.)

위 두가지 사항 검토하여 답변 부탁드립니다.
주말 잘 보내십시요.
감사합니다.

안녕하세요.

MAC_RAW모드는 직접 작성한 코드이신가요??

일단 MAC_RAW의 경우에는 직접 프로토콜을 구성하여 사용하신 것이기 때문에 정확한 답변을 드리려면 코드가 필요합니다.

또한, 보통 ethernet packet은 맨 앞에 packetlengh(패킷길이) + Packetdata 순으로 진행됩니다.

기본적으로 정상 통신할 경우, wireshark로 검출이 됩니다.

이 것이 만약 데이터가 올바르지 않다고 해도 검출 됩니다. 다만, 프로토콜이 이상할 경우, 캡쳐하지 못할 수 있습니다.

감사합니다.

안녕하세요. 관리자님.
답변 감사합니다.
저희는 주고 받는 패킷은 Mac Raw Packet형태로 그대로 uart를 통하여 퀄컴PLC 칩으로 넘겨주므로,
별도 TCP/IP 나 UDP/IP를 구현하지 않습니다.
(쉽게 말씀드린다면 Mac Raw Packet을 그대로 전달하도록 구현하고 있습니다.)
이에 wiz750SR소스를 mac raw소켓을 받을 수 있도록 수정하며 테스트 중에 있습니다.

소스수정은 비교적 간단하게 수정할 수 있더군요.
(아래 소스 부분중 밑줄부분 참고하시기 바랍니다. 즉, 세군데만 고치면 테스트 가능합니다.)
(수정한 펌웨어 업로딩후 wiz750sr모듈로 ping을 보내면 mac raw소켓을 받아보도록 할 수 있습니다.)

테스트를 해보면 Wiznet구동후 첫번째 수신하는 패킷은 잘 받아오는 것을 확인하였습니다.
즉, PacketLength(2byte) + PacketData 형태로 S0_RX_RD(버퍼 포인터)와 S0RX_RSR(수신 데이터 length) Register가 잘 동작하는 것을 확인하였습니다.
그러나, 정상적인 패킷 수신직후 do_seg()루틴을 다시 거치게 되면 S0_RX_RSR의 값이 65534으로 비정상적인 값을 읽어오면서, S0소켓을 close 및 초기화하기 전까지 S0소켓은 더이상 동작하지 않습니다.

이에 소스도 같이 송부하오니 답변 부탁드리겠습니다.
다시한번 답변 부탁드리겠습니다.
감사합니다.

void proc_SEG_udp(uint8_t sock)
{
DevConfig *s2e = get_DevConfig_pointer();
struct __network_info *net = (struct __network_info *)get_DevConfig_pointer()->network_info;
struct __serial_info *serial = (struct __serial_info *)get_DevConfig_pointer()->serial_info;

uint8_t state = getSn_SR(sock);
switch(state)
{
	case [b][i][u]SOCK_MACRAW[/u][/i][/b]://SOCK_UDP
		if(BUFFER_USED_SIZE(data_rx) || u2e_size)	uart_to_ether(sock);
		if(getSn_RX_RSR(sock) 	|| e2u_size)		ether_to_uart(sock);
		break;
		
	case SOCK_CLOSED:
		//reset_SEG_timeflags();
		BUFFER_CLEAR(data_rx);
	
		u2e_size = 0;
		e2u_size = 0;
		
		if(socket(sock, [b][i][u]Sn_MR_MACRAW[/u][/i][/b], net->local_port, 0) == sock)//Sn_MR_UDP
		{
			set_device_status(ST_UDP);
			
			if(net->packing_time) modeswitch_gap_time = net->packing_time; // replace the GAP time (default: 500ms)
			
			if(serial->serial_debug_en == SEG_ENABLE)
			{
				printf(" > SEG:UDP_MODE:SOCKOPEN\r\n");
			}
		}
		break;
	default:
		break;
}

}

void ether_to_uart(uint8_t sock)
{
struct __network_info *netinfo = (struct __network_info *)&(get_DevConfig_pointer()->network_info);
struct __serial_info *serial = (struct __serial_info *)get_DevConfig_pointer()->serial_info;
struct __options *option = (struct __options *)&(get_DevConfig_pointer()->options);
uint16_t len;
uint16_t i;

if(serial->flow_control == flow_rts_cts)
{

#ifdef USE_GPIO_HARDWARE_FLOWCONTROL
if(get_uart_cts_pin(SEG_DATA_UART) != UART_CTS_LOW) return;
#else
; // check the CTS reg
#endif
}

// H/W Socket buffer -> User's buffer
len = getSn_RX_RSR(sock);
if(len > DATA_BUF_SIZE) len = DATA_BUF_SIZE; // avoiding buffer overflow

//printf("ether_to_uart: %d\r\n", len); // ## for debugging

if(len > 0)
{
	switch(getSn_SR(sock))
	{
		case [b][i][u]SOCK_MACRAW[/u][/i][/b]://SOCK_UDP // UDP_MODE
			e2u_size = recvfrom(sock, g_recv_buf, len, peerip, &peerport);
			............................................................
	}
	..................................
}
.........................

}
WIZ750SR.zip (3.67 MB)

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.