Sida 1 av 1

Sända ett UDP-paket med AVR och ENC28j60

Postat: 27 juni 2015, 22:17:07
av PaNiC
Ja jag har hållit på ett tag nu. Använder https://github.com/jonoxer/etherShield/ ... _udp_tcp.c
Genom att skriva ut till en tillkopplad display har jag kunnat verifiera att arp-requesten går igenom och mac-adresser, ip-adresser, och datainnehåll stämmer i det utgående paketet. Kontrollsumman har jag inte kollat, då jag inte riktigt vet hur jag skulle bära mig åt.
Har jag missat något annat? Paketet verkar komma iväg, åtminstone blir funktionen Enc28j60PacketSend kallad på

Kod: Markera allt


unsigned char send_udp_packet(char *data, unsigned char *ip, uint16_t port)
{
unsigned int dlen = 0;
unsigned char dly = 0;
unsigned int plen = 0;
uint8_t *p;
unsigned char i = 0;
unsigned int ck = 0;
char str[20];

	while(data[dlen]){		//calculate data length
		dlen++;
	}

	Make_arp_request(buf, destip);			//arp request to find out dest's mac addr.
	while(!Enc28j60PacketReceive(BUFFER_SIZE, buf)){
		dly++;
		_delay_ms(1);
		if(dly > arptimeout){
			return 1;
		}

	}

	p = (uint8_t*) &(buf[ETH_ARP_SRC_MAC_P]); //assign dest MAC to packet
	Make_eth_ip_new(buf, p);				//make new ip header

	i = 0;
	while(i < 4)							//assign dest and src IP to packet
	{
		buf[IP_DST_P + i] = ip[i];
		buf[IP_SRC_P + i] = myip[i];
		i++;
	}

	buf[UDP_DST_PORT_H_P] = port >> 8;		//assign port to packet
	buf[UDP_DST_PORT_L_P] = port & 0xff;

	buf[UDP_LEN_H_P] = 0;					//assign data length to packet
	buf[UDP_LEN_L_P] = UDP_HEADER_LEN + dlen;
	
	buf[UDP_CHECKSUM_H_P] = 0;				//zero the checksum
	buf[UDP_CHECKSUM_L_P] = 0;

	i = 0;
	while(i < dlen)					//copy data to packet
	{
		buf[UDP_DATA_P + i] = data[i];
		i++;
	}

	ck = Checksum(&buf[IP_SRC_P], 16 + dlen, 1);			//calculate checksum
	buf[UDP_CHECKSUM_H_P] = ck >> 8;				//assign checksum to packet
	buf[UDP_CHECKSUM_L_P] = ck & 0xff;

	Enc28j60PacketSend(UDP_HEADER_LEN + IP_HEADER_LEN + ETH_HEADER_LEN + dlen, buf);
	return 0;
}

Använder "nc -u -lp 23" för att lyssna på maskinen jag skickar till.
Kallar på funktionen med:

Kod: Markera allt

	destip[0] = 172;
	destip[1] = 17;
	destip[2] = 32;
	destip[3] = 254;





	if(send_udp_packet("Hello\n", destip, 23)){
		sprintf(str, "Fail");
		FB_writestringram(0,48,str);
		LCD_update(1);
	
	}

Re: Sända ett UDP-paket med AVR och ENC28j60

Postat: 28 juni 2015, 21:24:00
av PaNiC
Så, löst. Wireshark sade "Bogus IP header length". Visade sig att jag hade missat att stoppa dit den, samt att speca protokollet till UDP. Nu funkar det!

Kod: Markera allt

unsigned char send_udp_packet(char *data, unsigned char *ip, uint16_t port)
{
unsigned int dlen = 0;
unsigned char dly = 0;
uint8_t *p;
unsigned char i = 0;
unsigned int ck = 0;
char str[20];

	while(data[dlen]){		//calculate data length
		dlen++;
	}

	Make_arp_request(buf, destip);			//arp request to find out dest's mac addr.
	while(!Enc28j60PacketReceive(BUFFER_SIZE, buf)){


		dly++;
		_delay_ms(1);
		if(dly > arptimeout){
			return 1;
		}

	}
		
	buf[IP_TOTLEN_H_P] = 0;					//assign packet length to packet
	buf[IP_TOTLEN_L_P] = IP_HEADER_LEN + UDP_HEADER_LEN + dlen;

	buf[UDP_LEN_H_P] = 0;					//assign header length to packet
	buf[UDP_LEN_L_P] = UDP_HEADER_LEN;

	buf[IP_P] = IP_V4_V | IP_HEADER_LENGTH_V;
	buf[IP_PROTO_P] = IP_PROTO_UDP_V;

	Fill_ip_hdr_checksum(buf);

	p = (uint8_t*) &(buf[ETH_ARP_SRC_MAC_P]); //assign dest MAC to packet
	Make_eth_ip_new(buf, p);				//make new ip header

	i = 0;
	while(i < 4)							//assign dest and src IP to packet
	{
		buf[IP_DST_P + i] = ip[i];
		buf[IP_SRC_P + i] = myip[i];
		i++;
	}

	buf[UDP_DST_PORT_H_P] = port >> 8;		//assign port to packet
	buf[UDP_DST_PORT_L_P] = port & 0xff;

	buf[UDP_LEN_H_P] = 0;					//assign data length to packet
	buf[UDP_LEN_L_P] = UDP_HEADER_LEN + dlen;
	
	buf[UDP_CHECKSUM_H_P] = 0;				//zero the checksum
	buf[UDP_CHECKSUM_L_P] = 0;

	i = 0;

	while(i < dlen)
	{
		buf[UDP_DATA_P + i] = data[i];
		i++;
	}

	ck = Checksum(&buf[IP_SRC_P], 16 + dlen, 1);	//calculate checksum
	buf[UDP_CHECKSUM_H_P] = ck >> 8;				//assign checksum to packet
	buf[UDP_CHECKSUM_L_P] = ck & 0xff;

	Enc28j60PacketSend(UDP_HEADER_LEN + IP_HEADER_LEN + ETH_HEADER_LEN + dlen, buf);

	return 0;
}

Re: Sända ett UDP-paket med AVR och ENC28j60

Postat: 29 juni 2015, 11:24:16
av adent
Vad körde du för AVR? Hur mycket flash tog "drivrutin" och "TCP/IP"-stack (krympt till UDP-IP antar jag?)

MVH: Mikael

Re: Sända ett UDP-paket med AVR och ENC28j60

Postat: 29 juni 2015, 16:10:59
av PaNiC
Kör med Mega328 nu. Har inte riktigt koll på hur mycket minne det tar, har tryckt in en del annat. Strax under 1kB gissar jag.