RPC Over TCP(telnet) Command format is same as serial RPC (not HTTP RPC). Please find attached Test Program(Processing and ActionScript3) at end of this file. Same functionality of Serial RPC via Serproxy.

Dependencies:   EthernetNetIf mbed

Revision:
0:a0cd4d9690f0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Nov 19 17:19:03 2010 +0000
@@ -0,0 +1,470 @@
+/*
+ *
+ * RPC over TCP (RPC over telnet)
+ * (Same functionality of Serial RPC via Serproxy )
+ *
+ * Command format is same as serial RPC (not HTTP RPC)
+ *
+ * (example)
+ * So you can control mbed by sending the followng command (over UDP)
+ * /DigitalOut/new LED1 myled
+ * /myled/write 1
+ * /AnalogIn/new p20 ain
+ * /ain/read
+ *
+ * Please find attached Test Programs(processing & ActionScript3) at end of this file as comment "#if 0"
+ *
+ * Serproxy(Serial Proxy) source&binary can be downloaded from:
+ *  http://cote.cc/blog/serialproxy-v014-can-use-com-ports-above-9
+ *  http://cote.cc/sites/default/files/serproxy-0.1.4.win32.zip
+ *  http://cote.cc/sites/default/files/serproxy-0.1.4.src_.zip
+ *
+ */
+
+// 2010/11/20
+// written by: xshige
+
+
+// please change port# if you need
+#define TCP_LISTENING_PORT 5335 // telnet port
+
+#define DEBUG
+//#define DHCP
+//#define LIVE_LED
+
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "TCPSocket.h"
+#include "rpc.h"
+
+#ifdef DHCP
+EthernetNetIf eth;
+#else
+// please set your mbed IP
+EthernetNetIf eth(
+  IpAddr(192,168,0,25), //IP Address
+  IpAddr(255,255,255,0), //Network Mask
+  IpAddr(192,168,0,1), //Gateway
+  IpAddr(192,168,0,1)  //DNS
+);
+#endif
+
+#ifdef LIVE_LED
+DigitalOut led4(LED4, "led4");
+#endif
+
+
+// receive commands, and send back the responses
+char inbuf[512], outbuf[512];
+
+TCPSocket ListeningSock;
+TCPSocket* pConnectedSock; // for ConnectedSock
+Host client;
+TCPSocketErr err;
+
+void onConnectedTCPSocketEvent(TCPSocketEvent e)
+{
+   switch(e)
+    {
+    case TCPSOCKET_CONNECTED:
+        printf("TCP Socket Connected\r\n");
+        break;
+    case TCPSOCKET_WRITEABLE:
+        //Can now write some data...
+//        printf("TCP Socket Writable\r\n");
+        break;
+    case TCPSOCKET_READABLE:
+        //Can now read dome data...
+ //       printf("TCP Socket Readable\r\n");
+//-------------------------------------
+        // Read in any available data into the buffer
+        int len = pConnectedSock->recv(inbuf, 512);
+        inbuf[len] = 0;
+#ifdef DEBUG        
+        printf("\nReceived: %s", inbuf);
+#endif        
+        // do RPC
+        if (len>0) {
+            rpc(inbuf, outbuf); 
+            outbuf[strlen(outbuf)]=0;
+            // send result of RPC
+            pConnectedSock->send(outbuf, strlen(outbuf));
+#ifdef DEBUG            
+            printf("Sent:%s\n",outbuf);
+#endif
+        }
+       break;
+//----------------------------------------
+    case TCPSOCKET_CONTIMEOUT:
+        printf("TCP Socket Timeout\r\n");
+        break;
+    case TCPSOCKET_CONRST:
+        printf("TCP Socket CONRST\r\n");
+        break;
+    case TCPSOCKET_CONABRT:
+        printf("TCP Socket CONABRT\r\n");
+        break;
+    case TCPSOCKET_ERROR:
+        printf("TCP Socket Error\r\n");
+        break;
+    case TCPSOCKET_DISCONNECTED:
+        printf("TCP Socket Disconnected\r\n");        
+//        pConnectedSock->close();
+        break;
+    default:
+        printf("DEFAULT\r\n"); 
+      }
+}
+
+
+void onListeningTCPSocketEvent(TCPSocketEvent e)
+{
+    switch(e)
+    {
+    case TCPSOCKET_ACCEPT:
+        printf("Listening: TCP Socket Accepted\r\n");
+        // Accepts connection from client and gets connected socket.   
+        err=ListeningSock.accept(&client, &pConnectedSock);
+        if (err) {
+            printf("onListeningTcpSocketEvent : Could not accept connection.\r\n");
+            return; //Error in accept, discard connection
+        }
+        // Setup the new socket events
+        pConnectedSock->setOnEvent(&onConnectedTCPSocketEvent);
+        // We can find out from where the connection is coming by looking at the
+        // Host parameter of the accept() method
+        IpAddr clientIp = client.getIp();
+        printf("Listening: Incoming TCP connection from %d.%d.%d.%d\r\n", 
+           clientIp[0], clientIp[1], clientIp[2], clientIp[3]);
+       break;
+    // the following cases will not happen
+    case TCPSOCKET_CONNECTED:
+        printf("Listening: TCP Socket Connected\r\n");
+        break;
+    case TCPSOCKET_WRITEABLE:
+        printf("Listening: TCP Socket Writable\r\n");
+        break;
+    case TCPSOCKET_READABLE:
+        printf("Listening: TCP Socket Readable\r\n");
+        break;
+    case TCPSOCKET_CONTIMEOUT:
+        printf("Listening: TCP Socket Timeout\r\n");
+        break;
+    case TCPSOCKET_CONRST:
+        printf("Listening: TCP Socket CONRST\r\n");
+        break;
+    case TCPSOCKET_CONABRT:
+        printf("Listening: TCP Socket CONABRT\r\n");
+        break;
+    case TCPSOCKET_ERROR:
+        printf("Listening: TCP Socket Error\r\n");
+        break;
+    case TCPSOCKET_DISCONNECTED:
+    //Close socket...
+        printf("Listening: TCP Socket Disconnected\r\n");       
+     //  keep socket for next connection //ListeningSock.close();
+        break;
+    default:
+        printf("DEFAULT\r\n"); 
+     };
+}
+
+
+int main() {
+
+// make debug port Fast
+   Serial pc(USBTX, USBRX);
+//    pc.baud(9600);
+    pc.baud(115200);
+//  pc.baud(230400);
+
+    
+ // setup the classes that can be created dynamically
+    Base::add_rpc_class<AnalogIn>();
+    Base::add_rpc_class<AnalogOut>();
+    Base::add_rpc_class<DigitalIn>();
+    Base::add_rpc_class<DigitalOut>();
+    Base::add_rpc_class<DigitalInOut>();
+    Base::add_rpc_class<PwmOut>();
+    Base::add_rpc_class<Timer>();
+    Base::add_rpc_class<SPI>();
+    Base::add_rpc_class<BusOut>();
+    Base::add_rpc_class<BusIn>();
+    Base::add_rpc_class<BusInOut>();
+    Base::add_rpc_class<Serial>();
+    
+    // setup network
+    printf("\r\n");
+    printf("Setting up...\r\n");
+    EthernetErr ethErr = eth.setup();
+    if(ethErr)
+    {
+        printf("Error %d in setup.\r\n", ethErr);
+        return -1;
+    }
+    printf("RPC over TCP(telnet) Setup OK\r\n");
+
+    IpAddr ip = eth.getIp();
+    printf("mbed IP Address is %d.%d.%d.%d:%d\r\n", ip[0], ip[1], ip[2], ip[3],(TCP_LISTENING_PORT));
+
+    // Set the callbacks for Listening
+    ListeningSock.setOnEvent(&onListeningTCPSocketEvent); 
+  
+    // bind and listen on TCP
+    err=ListeningSock.bind(Host(IpAddr(), TCP_LISTENING_PORT));
+    printf("Binding..\r\n");
+    if(err)
+    {
+        //Deal with that error...
+        printf("Binding Error\n");
+    }
+    
+    err=ListeningSock.listen(); // Starts listening
+    printf("Listening...\r\n");
+    if(err)
+    {
+        printf("Listening Error\r\n");
+    }
+ 
+#ifdef LIVE_LED 
+  Timer tmr;
+  tmr.start();
+#endif
+
+
+  while(true)
+  {
+    Net::poll();
+
+#ifdef LIVE_LED
+    if(tmr.read() > 0.2) // sec
+    {
+      led4=!led4; //Show that we are alive
+      tmr.reset();
+    }
+#endif
+  }  
+}
+#if 0
+//------------------------------------------------------------------------
+// Test Program (written in processing)
+
+/*
+ *
+ * RPC over TCP(telnet) or
+ * Serial RPC (via Serproxy)
+ * Test Program
+ * 
+ */
+    
+import processing.net.*; 
+
+// please setup remoteIP for yor enviroment
+String remoteIP = "192.168.0.25"; // server IP
+//String remoteIP = "127.0.0.1"; // (Serproxy case)
+int TELNET_PORT = 5335;
+
+Client myClient; 
+String dataIn; 
+ 
+void setup() { 
+  size(200, 200); 
+  myClient = new Client(this, remoteIP, TELNET_PORT); 
+} 
+    
+void draw() {}  // Empty draw keeps the program running
+
+/* 
+ * on key pressed event:
+ * pressing a key sends predefined command
+ */
+void keyPressed() {
+    String cmd="";
+// Real Serial RPC needs terminator("\r\n")
+    if (key == '1') cmd="/";
+    //
+    if (key == '2') cmd="/AnalogIn/new p20 ain";
+    if (key == '3') cmd="/ain/read";
+    //
+    if (key == '4') cmd="/AnalogOut/new p18 aout";
+    if (key == '5') cmd="/aout/";
+    if (key == '6') cmd="/aout/write_u16 4123";    
+//   if (key == '4') cmd="/BusIn/new bin p23 p22 p21";
+//   if (key == '5') cmd="/bin/read";
+    //   
+    if (key == '8') cmd="/DigitalOut/new LED4 myled4";
+    if (key == '9') cmd="/myled4/write 1";
+    if (key == '0') cmd="/myled4/write 0";    
+
+    // send the command
+    // ***  Serial RPC needs terminator("\n") **
+    myClient.write(cmd+"\n");
+ 
+}
+
+// ClientEvent message is generated when the server 
+// sends data to an existing client.
+void clientEvent(Client someClient) {
+    if (someClient.available()>0) {
+      dataIn = someClient.readString(); 
+      //println(dataIn);       
+      print(dataIn); 
+    }
+
+}
+#endif
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+#if 0
+// TelnetClient.as
+
+/*
+ *
+ * RPC over TCP(telnet) or
+ * Serial RPC (via Serproxy)
+ * Test Program
+ * 
+ */
+
+package {
+        import flash.display.Sprite;
+        import flash.events.Event;
+        import flash.events.IOErrorEvent;
+        import flash.events.KeyboardEvent;
+        import flash.events.ProgressEvent;
+        import flash.events.SecurityErrorEvent;
+        import flash.net.Socket;
+        import flash.text.*;
+        import flash.ui.Keyboard;
+
+        public class TelnetClient extends Sprite
+        {
+				// please set your mbed IP
+				private var targetIP:String = "192.168.0.25";
+				//private var targetIP:String = "127.0.0.1";
+				//
+				private var targetPort:String = "5335";
+				//private var targetPort:String = "5334";
+
+				private var socket:Socket;
+                private var textView:TextField;
+                private var textBoard:TextField;
+				
+                public function TelnetClient()
+                {
+						// setup text field
+                        textView        = addTextField( 5, 10, 640, 340+190 );
+                        textBoard       = addTextField( 5, 340+200, 640, 20 ); // input field
+
+			            // Create a new Socket object and assign event listeners.
+						socket = new Socket();
+						
+                        socket.addEventListener( Event.CONNECT, onConnect );
+                        socket.addEventListener( Event.CLOSE, onClose );
+                        socket.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurtyError );
+                        socket.addEventListener( IOErrorEvent.IO_ERROR,onIOError );
+                        socket.addEventListener(ProgressEvent.SOCKET_DATA, onRead );
+                        addEventListener( KeyboardEvent.KEY_DOWN, onWriteBoard );
+
+			            // Attempt to connect to remote socket server.
+            			try {
+                			writeView("trying to connect to " + targetIP + ":" + targetPort +'\n');
+               				 socket.connect(targetIP, parseInt(targetPort));
+            			} catch (error:Error) {
+                		/*
+                    		Unable to connect to remote server, display error
+                    		message and close connection.
+                		*/
+                			writeView(error.message+'\n');
+                			socket.close();
+            			}
+
+                }
+
+                public function onConnect( event:Event ):void
+                {
+                        writeView( "server connected\n" );
+                }
+
+                public function onClose( event:Event ):void
+                {
+                        writeView( "server close\n" );
+                }
+
+                public function onSecurtyError( ev:Event ):void
+                {
+                        writeView( "Security error.\n" );
+                }
+
+                public function onIOError( ev:Event ):void
+                {
+                       writeView( "IOError.\n" );
+                }
+
+                public function onRead( event:Event ):void
+                {
+                        writeView( socket.readUTFBytes(socket.bytesAvailable ) );
+                }
+
+                public function onWriteBoard( event:KeyboardEvent ):void
+                {
+                        if( !socket.connected ) return;
+                        if( event.keyCode == Keyboard.ENTER )
+                        {
+							// Shortcut Keys for testing RPC
+							if (textBoard.text == "1") textBoard.text = "/";
+							if (textBoard.text == "2") textBoard.text = "/AnalogIn/new p20 ain";
+							if (textBoard.text == "3") textBoard.text = "/ain/read";	
+							//
+							//if (textBoard.text == "4") textBoard.text = "/AnalogOut/new p18 aout";	
+							//if (textBoard.text == "5") textBoard.text = "/aout/";	
+							//if (textBoard.text == "6") textBoard.text = "/aout/write_u16 4123";	
+							//
+							if (textBoard.text == "4") textBoard.text = "/BusOut/new b0 LED1 LED2 LED3 LED4";	
+							if (textBoard.text == "5") textBoard.text = "/bo/write  13";	
+							//   
+							if (textBoard.text == "8") textBoard.text = "/DigitalOut/new LED4 myled4";	
+							if (textBoard.text == "9") textBoard.text = "/myled4/write 1";	
+							if (textBoard.text == "0") textBoard.text = "/myled4/write 0";	
+							//
+							socket.writeUTFBytes( textBoard.text + '\n' );
+							socket.flush();
+                            textBoard.text = '';
+                        }
+                }
+
+                public function writeView( str:String ):void
+                {
+                        if( textView.text == '' )
+                        {
+                                textView.text = str;
+                        }
+                        else {
+                        //        textView.text = textView.text + '\n' + str;
+                        //        textView.text = textView.text + str;
+							textView.appendText(str+'\n'); // serial RPC via serproxy
+						}
+						//	
+						textView.scrollV++; // make scroll
+                }
+
+                private function addTextField( x:int, y:int, w:uint,h:uint ):TextField
+                {
+                        var textField:TextField = new TextField();
+                        addChild( textField );
+                        textField.x             = x;
+                        textField.y             = y;
+                        textField.width         = w;
+                        textField.height        = h;
+                        textField.text          = "";
+                        textField.selectable    = true;
+                        textField.border        = true;
+                        textField.type          = TextFieldType.INPUT;
+						textField.wordWrap		= true;
+                        return textField;
+                }
+
+        }
+}
+#endif
+//------------------------------------------------------------------------