Sända ett UDP-paket med AVR och ENC28j60

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

Sända ett UDP-paket med AVR och ENC28j60

Inlägg 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);
	
	}
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

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

Inlägg 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;
}
Användarvisningsbild
adent
Inlägg: 4245
Blev medlem: 27 november 2008, 22:56:23
Ort: Utanför Jönköping
Kontakt:

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

Inlägg 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
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

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

Inlägg 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.
Skriv svar