// UDP默认端口号 #define UDP_AVR_PORT_V 3000 #define UDP_AVR_PORT_H_V (UDP_AVR_PORT_V>>8) #define UDP_AVR_PORT_L_V (UDP_AVR_PORT_V&0xff) // 源端口 #define UDP_SRC_PORT_H_P 0x22 #define UDP_SRC_PORT_L_P 0x23 // 目标端口 #define UDP_DST_PORT_H_P 0x24 #define UDP_DST_PORT_L_P 0x25 // UDP负载长度 #define UDP_LENGTH_H_P 0x26 #define UDP_LENGTH_L_P 0x27 // UDP校验和 #define UDP_CHECKSUM_H_P 0x28 #define UDP_CHECKSUM_L_P 0x29 // UDP负载起始地址 #define UDP_DATA_P 0x2A
#define UDP_AVR_PORT_V 3000 #define UDP_AVR_PORT_H_V (UDP_AVR_PORT_V>>8) #define UDP_AVR_PORT_L_V (UDP_AVR_PORT_V&0xff)
void udp_generate_header ( BYTE *rxtx_buffer, WORD_BYTES dest_port, WORD_BYTES length )
{
WORD_BYTES ck;
// 默认端口号 3000
rxtx_buffer[UDP_SRC_PORT_H_P] = UDP_AVR_PORT_H_V;
rxtx_buffer[UDP_SRC_PORT_L_P] = UDP_AVR_PORT_L_V;
// 目标端口地址
rxtx_buffer[UDP_DST_PORT_H_P] = dest_port.byte.high;
rxtx_buffer[UDP_DST_PORT_L_P] = dest_port.byte.low;
// 负载长度
rxtx_buffer[UDP_LENGTH_H_P] = length.byte.high;
rxtx_buffer[UDP_LENGTH_L_P] = length.byte.low;
// 计算校验和
rxtx_buffer[UDP_CHECKSUM_H_P] = 0;
rxtx_buffer[UDP_CHECKSUM_L_P] = 0;
// length+8 for source/destination IP address length (8-bytes)
ck.word = software_checksum ( (BYTE*)&rxtx_buffer[IP_SRC_IP_P], length.word+8, length.word+IP_PROTO_UDP_V);
rxtx_buffer[UDP_CHECKSUM_H_P] = ck.byte.high;
rxtx_buffer[UDP_CHECKSUM_L_P] = ck.byte.low;
}
WORD udp_get_dlength( BYTE *rxtx_buffer )
{
WORD length = 0;
// 获得UDP长度
length = rxtx_buffer[UDP_LENGTH_H_P] << 8 | rxtx_buffer[UDP_LENGTH_L_P];
// 去除首部长度
length = length - 8;
return length;
}
WORD udp_puts_data ( BYTE *rxtx_buffer, BYTE *data, WORD offset )
{
while(*data)
{
rxtx_buffer[UDP_DATA_P + offset] = *data++;
offset++;
}
return offset;
}
BYTE udp_receive ( BYTE *rxtx_buffer, BYTE *dest_mac, BYTE *dest_ip )
{
WORD dlength = 0;
// udp负载长度
WORD udp_loadlen = 0;
// 匹配UDP协议 UDP端口号
if ( rxtx_buffer[IP_PROTO_P] == IP_PROTO_UDP_V && rxtx_buffer[UDP_DST_PORT_H_P] == UDP_AVR_PORT_H_V && rxtx_buffer[ UDP_DST_PORT_L_P ] == UDP_AVR_PORT_L_V )
{
// 获得UDP负载长度
udp_loadlen = udp_get_dlength(rxtx_buffer);
// 复制UDP接收
memcpy(udp_recbuf, (char*)&rxtx_buffer[UDP_DATA_P], udp_loadlen);
#if UDP_DEBUG
printf("UDP Message!\r\n");
printf("Send Form:%d.%d.%d.%d ", rxtx_buffer[IP_SRC_IP_P+0],rxtx_buffer[IP_SRC_IP_P+1], rxtx_buffer[IP_SRC_IP_P+2],rxtx_buffer[IP_SRC_IP_P+3]);
printf("Port:%d\r\n",(rxtx_buffer[UDP_SRC_PORT_H_P] << 8) | rxtx_buffer[UDP_SRC_PORT_L_P]);
printf("Reccive:%s\r\n",udp_recbuf);
#endif
// 生成以太网首部
eth_generate_header(rxtx_buffer, (WORD_BYTES){ETH_TYPE_IP_V}, dest_mac );
// 生成IP首部
ip_generate_header(rxtx_buffer, (WORD_BYTES){sizeof(IP_HEADER)+sizeof(UDP_HEADER)+dlength}, IP_PROTO_UDP_V, dest_ip );
// 生成UDP首部
udp_generate_header(rxtx_buffer, (WORD_BYTES){(rxtx_buffer[UDP_SRC_PORT_H_P]<<8)|rxtx_buffer[UDP_SRC_PORT_L_P]}, (WORD_BYTES){sizeof(UDP_HEADER)+dlength});
// 发送所有首部和UDP负载数据
enc28j60_packet_send(rxtx_buffer, sizeof(ETH_HEADER)+sizeof(IP_HEADER)+sizeof(UDP_HEADER)+dlength );
// 返回1代表数据包已被处理
return 1;
}
// 返回0代表数据包未被处理
return 0;
}
// 获得新的IP报文
plen = enc28j60_packet_receive( (BYTE*)&rxtx_buffer, MAX_RXTX_BUFFER );
if(plen==0) return;
// 保存客服端的MAC地址
memcpy ( (BYTE*)&client_mac, &rxtx_buffer[ ETH_SRC_MAC_P ], sizeof( MAC_ADDR) );
// 检查该报文是不是ARP报文
if ( arp_packet_is_arp( rxtx_buffer, (WORD_BYTES){ARP_OPCODE_REQUEST_V} ) )
{
// 向客户端返回ARP报文
arp_send_reply ( (BYTE*)&rxtx_buffer, (BYTE*)&client_mac );
return;
}
// 保存客服端的IP地址
memcpy ( (BYTE*)&client_ip, &rxtx_buffer[ IP_SRC_IP_P ], sizeof(IP_ADDR) );
// 检查该报文是否为IP报文
if ( ip_packet_is_ip ( (BYTE*)&rxtx_buffer ) == 0 )
{
return;
}
// 如果是ICMP报文 向发起方返回数据
if ( icmp_send_reply ( (BYTE*)&rxtx_buffer, (BYTE*)&client_mac, (BYTE*)&client_ip ) )
{
return;
}
// 进行UDP处理
if (udp_receive ( (BYTE *)&rxtx_buffer, (BYTE *)&client_mac, (BYTE *)&client_ip ))
{
return;
}
// 获得UDP负载长度
udp_loadlen = udp_get_dlength(rxtx_buffer);
// 复制UDP接收
memcpy(udp_recbuf, (char*)&rxtx_buffer[UDP_DATA_P], udp_loadlen);
#if UDP_DEBUG
printf("UDP Message!\r\n");
printf("Send Form:%d.%d.%d.%d ", rxtx_buffer[IP_SRC_IP_P+0],rxtx_buffer[IP_SRC_IP_P+1], rxtx_buffer[IP_SRC_IP_P+2],rxtx_buffer[IP_SRC_IP_P+3]);
printf("Port:%d\r\n",(rxtx_buffer[UDP_SRC_PORT_H_P] << 8) | rxtx_buffer[UDP_SRC_PORT_L_P]);
printf("Reccive:%s\r\n",udp_recbuf);
#endif
#if UDP_ECHO
// Hello 范例
// 复制Hello
strcpy(udp_sendbuf,"UDP:Hello ");
// 连接数据
strcat(udp_sendbuf, udp_recbuf);
dlength = udp_puts_data(rxtx_buffer, (BYTE*)udp_sendbuf, 0);
#endif
#if UDP_LEDCTRL
int match_count = 0;
int led_index = 0;
int led_status = 0;
// 匹配led,x,y
match_count = sscanf(udp_recbuf,"led,%d,%d", &led_index, &led_status);
if(match_count == 2)
{
switch(led_index)
{
case 1:
led_status?BSP_LEDOn(1):BSP_LEDOff(1);
dlength = udp_puts_data(rxtx_buffer, (BYTE*)"LED1 Control OK\r\n", 0);
break;
case 2:
led_status?BSP_LEDOn(2):BSP_LEDOff(2);
dlength = udp_puts_data(rxtx_buffer, (BYTE*)"LED2 Control OK\r\n", 0);
break;
default:
dlength = udp_puts_data(rxtx_buffer, (BYTE*)"Invalid Led Index\r\n", 0);
break;
}
}
else
{
dlength = udp_puts_data(rxtx_buffer, (BYTE*)"unknow command\r\n", 0);
}
#endif STM32NET学习笔记 UDP部分,布布扣,bubuko.com
原文:http://blog.csdn.net/xukai871105/article/details/23103539