Commits

bjoern committed 7c35b11

added bytewise read of UDP data and example

Comments (0)

Files changed (3)

libraries/Ethernet/UdpBytewise.cpp

 void UdpBytewiseClass::begin(uint16_t port) {
 	_port = port;
 	_sock = 0; //TODO: should not be hardcoded
-	_index =0;
+	_txIndex =0;
+	_rxIndex =0;
+	_rxSize = 0;
 	socket(_sock,Sn_MR_UDP,_port,0);
 }
 
 
 /* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes. */
 int UdpBytewiseClass::available() {
-	return getSn_RX_RSR(_sock);
+	if(_rxSize==0 || _rxSize-_rxIndex==0) { 
+		//if local buffer is empty or depleted
+		//check wiz5100 buffer for new packet
+		_rxSize = getSn_RX_RSR(_sock); //this size is inflated by 8 byte header
+		if(_rxSize){
+			//if we have a new packet there
+			//copy it into our local buffer
+			_rxIndex=0;
+			_rxSize = recvfrom(_sock,_rxBuffer,_rxSize-8,_rxIp,&_rxPort);
+		} else {
+			//else do nothing and rxsize is still 0
+			;
+		}
+		return _rxSize; //return the new number of bytes in our buffer
+	} else{
+		//if buffer is not empty, return remaining # of bytes
+		return (_rxSize-_rxIndex);
+	}
+	
 }
 
 
 
 int UdpBytewiseClass::beginPacket(uint8_t *ip, unsigned int port) { // returns 1 on success, 0 if we already started a packet
-	if(_index==0) {
-		_remoteIp[0]=ip[0];
-		_remoteIp[1]=ip[1];
-		_remoteIp[2]=ip[2];
-		_remoteIp[3]=ip[3];
-		_remotePort = port;
+	if(_txIndex==0) {
+		_txIp[0]=ip[0];
+		_txIp[1]=ip[1];
+		_txIp[2]=ip[2];
+		_txIp[3]=ip[3];
+		_txPort = port;
 		return 1;
 	}
 	else {
 // TODO: how do we indicate that we can't add to full buffer?
 // or do we just send a full packet and start the next?
 void UdpBytewiseClass::write(uint8_t b) {// add a byte to the currently assembled packet if there is space
-	if(_index>= UDP_TX_PACKET_MAX_SIZE)
+	if(_txIndex>= UDP_TX_PACKET_MAX_SIZE)
 		return;		
-	_buffer[_index++] = b;
+	_txBuffer[_txIndex++] = b;
 }
 
 int UdpBytewiseClass::endPacket(){ // returns # of bytes sent on success, 0 if there's nothing to send
 	// send the packet
-	uint16_t result = sendto(_sock,(const uint8_t *)_buffer,_index,_remoteIp,_remotePort);
+	uint16_t result = sendto(_sock,(const uint8_t *)_txBuffer,_txIndex,_txIp,_txPort);
 	// reset buffer index
-	_index=0;
+	_txIndex=0;
 	// return sent bytes
 	return (int)result;
 }
 
-
+int UdpBytewiseClass::read() {
+	if(_rxIndex!=_rxSize) {
+		//if there is something to be read
+		//return the next byte
+		return _rxBuffer[_rxIndex++];
+		
+	} else {
+		//we already sent the last byte
+		//reset our buffer
+		_rxIndex=0;
+		_rxSize=0;
+		return -1;
+	}
+}
+	
+void UdpBytewiseClass::getSenderIp(uint8_t*ip) {
+	ip[0]=_rxIp[0];
+	ip[1]=_rxIp[1];
+	ip[2]=_rxIp[2];
+	ip[3]=_rxIp[3];
+}
+	
+unsigned int  UdpBytewiseClass::getSenderPort() {
+	return _rxPort;
+}
 
 /* Create one global object */
 UdpBytewiseClass UdpBytewise;

libraries/Ethernet/UdpBytewise.h

 
 #include "Print.h"
 
-#define UDP_TX_PACKET_MAX_SIZE 24
+#define UDP_TX_PACKET_MAX_SIZE 32
+#define UDP_RX_PACKET_MAX_SIZE 32
 
 class UdpBytewiseClass: public Print {
 private:
 	uint8_t _sock;  // socket ID for Wiz5100
 	uint16_t _port; // local port to listen on
-	uint8_t _buffer[UDP_TX_PACKET_MAX_SIZE];
-	uint8_t _index;
-	uint8_t _remoteIp[4];
-	uint16_t _remotePort;
+	
+	uint8_t _txBuffer[UDP_TX_PACKET_MAX_SIZE];
+	uint8_t _txIndex;
+	uint8_t _txIp[4];
+	uint16_t _txPort;
+	
+	uint8_t _rxBuffer[UDP_RX_PACKET_MAX_SIZE];
+	uint8_t _rxIndex;
+	int _rxSize;
+	uint8_t _rxIp[4];
+	uint16_t _rxPort;
+	
 public:
 	void begin(uint16_t);				// initialize, start listening on specified port
 	int available();								// has data been received?
 	virtual void write(uint8_t); // add a byte to the currently assembled packet (if there's space)
 	int endPacket(); // returns # of bytes sent on success, 0 if there's nothing to send
 	
+	int read(); //read a byte if available - returns -1 if end of packet
+	void getSenderIp(uint8_t*ip);
+	unsigned int getSenderPort();
 };
 
 extern UdpBytewiseClass UdpBytewise;

libraries/Ethernet/examples/UdpReceiveBytewise/UdpReceiveBytewise.pde

+#include <Ethernet.h>
+#include <UdpBytewise.h>
+
+/* UdpReceiveBytewise.pde: Example how to receive packets over UDP using UdpBytewise library
+ * prints received packet to serial port
+ * bjoern@cs.stanford.edu 12/30/2008
+ */
+
+/* ETHERNET SHIELD CONFIGURATION  
+ * set MAC, IP address of Ethernet shield, its gateway,
+ * and local port to listen on for incoming packets 
+ */
+byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address to use
+byte ip[] = { 192, 168, 11, 200 }; // Arduino's IP address
+byte gw[] = { 192, 168, 11, 1 };   // Gateway IP address
+int localPort = 8888; // local port to listen on
+
+#define MAX_SIZE 32 // maximum packet size
+byte packetBuffer[MAX_SIZE]; //buffer to hold incoming packet
+int packetSize; // holds received packet size
+byte remoteIp[4]; // holds recvieved packet's originating IP
+unsigned int remotePort; // holds received packet's originating port
+
+int i;
+
+/* SETUP: init Ethernet shield, start UDP listening, open serial port */
+void setup() {
+  Ethernet.begin(mac,ip,gw);
+  UdpBytewise.begin(localPort);
+  Serial.begin(9600); 
+}
+/* LOOP: wait for incoming packets and print each packet to the serial port */
+void loop() {  
+  
+  // if there's data available, read a packet
+  if(packetSize = UdpBytewise.available()) {
+    Serial.print("Received packet of size ");
+    Serial.println(packetSize);
+    
+    UdpBytewise.getSenderIp(remoteIp);
+    Serial.print("From IP ");
+    for(i=0; i<3; i++) {
+      Serial.print(remoteIp[i],DEC);
+      Serial.print(".");
+    }
+    Serial.print(remoteIp[3],DEC);
+    
+    remotePort = UdpBytewise.getSenderPort();
+    Serial.print(" Port ");
+    Serial.println(remotePort); 
+    
+    Serial.println("Contents:");
+    while(UdpBytewise.available()) {
+      Serial.print(UdpBytewise.read(),BYTE);
+    }
+  }
+  //wait a bit
+  delay(10);  
+}