Learning how to use RPC.

Revision:
0:9232f9e1178d
Child:
1:67aefdc74b32
diff -r 000000000000 -r 9232f9e1178d RPCFunction.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RPCFunction.cpp	Thu Sep 16 13:27:57 2010 +0000
@@ -0,0 +1,145 @@
+/**
+*@section LICENSE
+*Copyright (c) 2010 ARM Ltd.
+*
+*Permission is hereby granted, free of charge, to any person obtaining a copy
+*of this software and associated documentation files (the "Software"), to deal
+*in the Software without restriction, including without limitation the rights
+*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*copies of the Software, and to permit persons to whom the Software is
+*furnished to do so, subject to the following conditions:
+* 
+*The above copyright notice and this permission notice shall be included in
+*all copies or substantial portions of the Software.
+* 
+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*THE SOFTWARE.
+*
+*@section Description
+*This class provides an object which can be called over RPC to run the function which is attached to it.
+*
+*/      
+#include "RPCFunction.h"
+#include "rpc.h"
+
+//Parse a char argument without delimiting by anything that is non alphanumeric - based on version in rpc.h line 153
+ char *parse_arg_char(const char *arg, const char **next) {
+        const char *ptr = arg;
+        char *res = NULL;
+        if(*arg == '"') {
+            /* quoted string */
+            ptr = ++arg;
+            int len = 0;
+            /* find the end (and length) of the quoted string */
+            for(char c = *ptr; c != 0 && c != '"'; c = *++ptr) {
+                len++;
+                if(c == '\\') {
+                    ptr++;
+                }
+            }  
+            /* copy the quoted string, and unescape characters */
+            if(len != 0) {
+                res = new char[len+1];
+                char *resptr = res;
+                while(arg != ptr) {
+                    *resptr++ = parse_char(arg, &arg);
+                }
+                *resptr = 0;
+            }
+        } else {
+            /* unquoted string */
+            while(isalnum(*ptr) || isgraph(*ptr) || *ptr=='_' || *ptr == ' ') {             //Edit this line to change which types of characters are allowed and which delimit
+                ptr++;
+           }
+            int len = ptr-arg;
+            if(len!=0) {                                //Chnages made to just pass whole string with no next arg or delimiters, these changes just removes space at the beginning
+                res = new char[len];                    //was len+1
+                memcpy(res, arg + 1, len - 1);          // was arg, len
+                res[len-1] = 0;                         //was len 
+            }
+        }
+      
+        if(next != NULL) {
+            *next = ptr;
+        } 
+      return res;
+    }  
+    //Custom rpc method caller for run so that the string will not be delimted by anything, one argument only
+    //based on code in rpc.h
+    void rpc_method_caller_run(Base *this_ptr, const char *arguments, char *result) {
+        const char *next = arguments;
+        char * arg1 = parse_arg_char(next,NULL);
+
+        (static_cast<RPCFunction*>(this_ptr)->run)(arg1);
+        
+        if(result != NULL) {
+            result[0] = '\0';
+        }
+    }
+    //Custom rpc method caller for execute so that the string will not be delimited by anything
+    //See line 436 of rpc.h
+    void rpc_method_caller_execute(Base *this_ptr, const char *arguments, char *result) {
+    
+        const char *next = arguments;
+        char* arg1 = parse_arg_char(next,NULL);
+        
+        char * res = (static_cast<RPCFunction*>(this_ptr)->execute)(arg1);
+        if(result != NULL) {
+            write_result<char*>(res, result);
+        }
+    }
+
+   RPCFunction::RPCFunction(void(*f)(char*, char*), const char* name) : Base(name){
+        _ftr = f;   
+    }
+    
+    //Function call which executes the packet
+    char* RPCFunction::execute(char * input){
+        strcpy(_input, input);
+        (*_ftr)(_input,_output);
+        return(_output);
+    }
+
+    //Just run the attached function using the string thats in private memory - or just using null values, 
+    void RPCFunction::run(char * str){
+        strcpy(_input, str);
+       (*_ftr)(_input,_output);
+    }
+    
+    //Just read the output string
+    char* RPCFunction::read(){
+        return(_output);
+    }
+    //Just set the input string
+    void RPCFunction::write(char * str){
+        strcpy(_input, str);
+    }
+    
+    
+    #ifdef MBED_RPC
+    const rpc_method *RPCFunction::get_rpc_methods() {
+       static const rpc_method rpc_methods[] = { 
+        {"execute", rpc_method_caller_execute },                                          //Run using custom caller, all character accepted in string
+        { "run", rpc_method_caller_run },                                                 //Run using custom caller, all character accepted in string
+        { "read", rpc_method_caller<char*, RPCFunction, &RPCFunction::read> },
+        { "write", rpc_method_caller<RPCFunction, char*, &RPCFunction::write> },
+        RPC_METHOD_SUPER(Base)
+      };
+      return rpc_methods;
+    }       
+         //creating a new one has very little meaning over RPC
+        rpc_class *RPCFunction::get_rpc_class() {
+        static const rpc_function funcs[] = { 
+            /*"new", rpc_function_caller<const char*, void(*f)(char*, char*), const char*, &Base::construct<Packet,void(*f)(char*, char*),const char*> >,*/
+            RPC_METHOD_END
+        };
+        static rpc_class c = { "RPCFunction", funcs, NULL };
+        return &c;
+    }
+#endif
+