Robin Hourahane / Improved-mbed-rpc

Fork of mbed-rpc by mbed official

Committer:
rhourahane
Date:
Mon Mar 23 20:10:24 2015 +0000
Revision:
9:6ce5db613c77
Parent:
1:6919289a5946
Child:
10:7511acfaa62d
Updates to remove possible buffer overflow issues.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:efe8172b4113 1 /* mbed Microcontroller Library
emilmont 1:6919289a5946 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 0:efe8172b4113 3 *
emilmont 1:6919289a5946 4 * Licensed under the Apache License, Version 2.0 (the "License");
emilmont 1:6919289a5946 5 * you may not use this file except in compliance with the License.
emilmont 1:6919289a5946 6 * You may obtain a copy of the License at
mbed_official 0:efe8172b4113 7 *
emilmont 1:6919289a5946 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 0:efe8172b4113 9 *
emilmont 1:6919289a5946 10 * Unless required by applicable law or agreed to in writing, software
emilmont 1:6919289a5946 11 * distributed under the License is distributed on an "AS IS" BASIS,
emilmont 1:6919289a5946 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
emilmont 1:6919289a5946 13 * See the License for the specific language governing permissions and
emilmont 1:6919289a5946 14 * limitations under the License.
mbed_official 0:efe8172b4113 15 */
mbed_official 0:efe8172b4113 16 #ifndef RPC_H
mbed_official 0:efe8172b4113 17 #define RPC_H
mbed_official 0:efe8172b4113 18
mbed_official 0:efe8172b4113 19 #include "mbed.h"
mbed_official 0:efe8172b4113 20 #include "Arguments.h"
mbed_official 0:efe8172b4113 21
mbed_official 0:efe8172b4113 22 namespace mbed {
mbed_official 0:efe8172b4113 23
mbed_official 0:efe8172b4113 24 #define RPC_MAX_STRING 128
mbed_official 0:efe8172b4113 25
mbed_official 0:efe8172b4113 26 struct rpc_function {
mbed_official 0:efe8172b4113 27 const char *name;
mbed_official 0:efe8172b4113 28 void (*function_caller)(Arguments*, Reply*);
mbed_official 0:efe8172b4113 29 };
mbed_official 0:efe8172b4113 30
mbed_official 0:efe8172b4113 31 struct rpc_class {
mbed_official 0:efe8172b4113 32 const char *name;
mbed_official 0:efe8172b4113 33 const rpc_function *static_functions;
mbed_official 0:efe8172b4113 34 struct rpc_class *next;
mbed_official 0:efe8172b4113 35 };
mbed_official 0:efe8172b4113 36
mbed_official 0:efe8172b4113 37 /* Class RPC
mbed_official 0:efe8172b4113 38 * The RPC class for most things
mbed_official 0:efe8172b4113 39 */
mbed_official 0:efe8172b4113 40 class RPC {
emilmont 1:6919289a5946 41
mbed_official 0:efe8172b4113 42 public:
emilmont 1:6919289a5946 43
mbed_official 0:efe8172b4113 44 RPC(const char *name = NULL);
mbed_official 0:efe8172b4113 45
mbed_official 0:efe8172b4113 46 virtual ~RPC();
mbed_official 0:efe8172b4113 47
mbed_official 0:efe8172b4113 48 /* Function get_rpc_methods
mbed_official 0:efe8172b4113 49 * Returns a pointer to an array describing the rpc methods
mbed_official 0:efe8172b4113 50 * supported by this object, terminated by either
mbed_official 0:efe8172b4113 51 * RPC_METHOD_END or RPC_METHOD_SUPER(Superclass).
mbed_official 0:efe8172b4113 52 *
mbed_official 0:efe8172b4113 53 * Example
mbed_official 0:efe8172b4113 54 * > class Example : public RPC {
mbed_official 0:efe8172b4113 55 * > int foo(int a, int b) { return a + b; }
mbed_official 0:efe8172b4113 56 * > virtual const struct rpc_method *get_rpc_methods() {
mbed_official 0:efe8172b4113 57 * > static const rpc_method rpc_methods[] = {
mbed_official 0:efe8172b4113 58 * > { "foo", generic_caller<int, Example, int, int, &Example::foo> },
mbed_official 0:efe8172b4113 59 * > RPC_METHOD_SUPER(RPC)
mbed_official 0:efe8172b4113 60 * > };
mbed_official 0:efe8172b4113 61 * > return rpc_methods;
mbed_official 0:efe8172b4113 62 * > }
mbed_official 0:efe8172b4113 63 * > };
mbed_official 0:efe8172b4113 64 */
mbed_official 0:efe8172b4113 65 virtual const struct rpc_method *get_rpc_methods();
rhourahane 9:6ce5db613c77 66
rhourahane 9:6ce5db613c77 67 // Virtual method to get the RPC class name of an object.
rhourahane 9:6ce5db613c77 68 // This allows a caller to discover the class of an existing
rhourahane 9:6ce5db613c77 69 // object.
rhourahane 9:6ce5db613c77 70 virtual const char *get_rpc_class_name();
emilmont 1:6919289a5946 71
mbed_official 0:efe8172b4113 72 static bool call(const char *buf, char *result);
mbed_official 0:efe8172b4113 73
mbed_official 0:efe8172b4113 74 /* Function lookup
mbed_official 0:efe8172b4113 75 * Lookup and return the object that has the given name.
mbed_official 0:efe8172b4113 76 *
mbed_official 0:efe8172b4113 77 * Variables
mbed_official 0:efe8172b4113 78 * name - the name to lookup.
mbed_official 0:efe8172b4113 79 */
mbed_official 0:efe8172b4113 80 static RPC *lookup(const char *name);
mbed_official 0:efe8172b4113 81
mbed_official 0:efe8172b4113 82 protected:
mbed_official 0:efe8172b4113 83 static RPC *_head;
mbed_official 0:efe8172b4113 84 RPC *_next;
mbed_official 0:efe8172b4113 85 char *_name;
mbed_official 0:efe8172b4113 86 bool _from_construct;
mbed_official 0:efe8172b4113 87
mbed_official 0:efe8172b4113 88 private:
mbed_official 0:efe8172b4113 89 static rpc_class *_classes;
mbed_official 0:efe8172b4113 90
mbed_official 0:efe8172b4113 91 static const rpc_function _RPC_funcs[];
mbed_official 0:efe8172b4113 92 static rpc_class _RPC_class;
mbed_official 0:efe8172b4113 93
mbed_official 0:efe8172b4113 94 void delete_self();
mbed_official 0:efe8172b4113 95 static void list_objs(Arguments *args, Reply *result);
rhourahane 9:6ce5db613c77 96
rhourahane 9:6ce5db613c77 97 // Populate result with a list of RPC classes that have been
rhourahane 9:6ce5db613c77 98 // registered with RPC.
rhourahane 9:6ce5db613c77 99 static void list_classes(Arguments *args, Reply *result);
mbed_official 0:efe8172b4113 100 static void clear(Arguments *args, Reply *result);
mbed_official 0:efe8172b4113 101
mbed_official 0:efe8172b4113 102 public:
mbed_official 0:efe8172b4113 103 /* Function add_rpc_class
mbed_official 0:efe8172b4113 104 * Add the class to the list of classes which can have static
mbed_official 0:efe8172b4113 105 * methods called via rpc (the static methods which can be called
mbed_official 0:efe8172b4113 106 * are defined by that class' get_rpc_class() static method).
mbed_official 0:efe8172b4113 107 */
mbed_official 0:efe8172b4113 108 template<class C>
mbed_official 0:efe8172b4113 109 static void add_rpc_class() {
mbed_official 0:efe8172b4113 110 rpc_class *c = C::get_rpc_class();
mbed_official 0:efe8172b4113 111 c->next = _classes;
mbed_official 0:efe8172b4113 112 _classes = c;
mbed_official 0:efe8172b4113 113 }
emilmont 1:6919289a5946 114
mbed_official 0:efe8172b4113 115 template<class C>
mbed_official 0:efe8172b4113 116 static const char *construct() {
mbed_official 0:efe8172b4113 117 RPC *p = new C();
mbed_official 0:efe8172b4113 118 p->_from_construct = true;
mbed_official 0:efe8172b4113 119 return p->_name;
mbed_official 0:efe8172b4113 120 }
emilmont 1:6919289a5946 121
mbed_official 0:efe8172b4113 122 template<class C, typename A1>
mbed_official 0:efe8172b4113 123 static const char *construct(A1 arg1) {
mbed_official 0:efe8172b4113 124 RPC *p = new C(arg1);
mbed_official 0:efe8172b4113 125 p->_from_construct = true;
mbed_official 0:efe8172b4113 126 return p->_name;
mbed_official 0:efe8172b4113 127 }
emilmont 1:6919289a5946 128
mbed_official 0:efe8172b4113 129 template<class C, typename A1, typename A2>
mbed_official 0:efe8172b4113 130 static const char *construct(A1 arg1, A2 arg2) {
mbed_official 0:efe8172b4113 131 RPC *p = new C(arg1, arg2);
mbed_official 0:efe8172b4113 132 p->_from_construct = true;
mbed_official 0:efe8172b4113 133 return p->_name;
mbed_official 0:efe8172b4113 134 }
emilmont 1:6919289a5946 135
mbed_official 0:efe8172b4113 136 template<class C, typename A1, typename A2, typename A3>
mbed_official 0:efe8172b4113 137 static const char *construct(A1 arg1, A2 arg2, A3 arg3) {
mbed_official 0:efe8172b4113 138 RPC *p = new C(arg1, arg2, arg3);
mbed_official 0:efe8172b4113 139 p->_from_construct = true;
mbed_official 0:efe8172b4113 140 return p->_name;
mbed_official 0:efe8172b4113 141 }
emilmont 1:6919289a5946 142
mbed_official 0:efe8172b4113 143 template<class C, typename A1, typename A2, typename A3, typename A4>
mbed_official 0:efe8172b4113 144 static const char *construct(A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
mbed_official 0:efe8172b4113 145 RPC *p = new C(arg1, arg2, arg3, arg4);
mbed_official 0:efe8172b4113 146 p->_from_construct = true;
mbed_official 0:efe8172b4113 147 return p->_name;
mbed_official 0:efe8172b4113 148 }
mbed_official 0:efe8172b4113 149 };
mbed_official 0:efe8172b4113 150
mbed_official 0:efe8172b4113 151 /* Macro MBED_OBJECT_NAME_MAX
mbed_official 0:efe8172b4113 152 * The maximum size of object name (including terminating null byte)
mbed_official 0:efe8172b4113 153 * that will be recognised when using fopen to open a FileLike
mbed_official 0:efe8172b4113 154 * object, or when using the rpc function.
mbed_official 0:efe8172b4113 155 */
mbed_official 0:efe8172b4113 156 #define MBED_OBJECT_NAME_MAX 32
mbed_official 0:efe8172b4113 157
mbed_official 0:efe8172b4113 158 /* Macro MBED_METHOD_NAME_MAX
mbed_official 0:efe8172b4113 159 * The maximum size of rpc method name (including terminating null
mbed_official 0:efe8172b4113 160 * byte) that will be recognised by the rpc function (in rpc.h).
mbed_official 0:efe8172b4113 161 */
mbed_official 0:efe8172b4113 162 #define MBED_METHOD_NAME_MAX 32
mbed_official 0:efe8172b4113 163
mbed_official 0:efe8172b4113 164 /* Function rpc_method_caller
mbed_official 0:efe8172b4113 165 */
rhourahane 9:6ce5db613c77 166 template<class T, void(T::*member)(Arguments *, Reply *)>
mbed_official 0:efe8172b4113 167 void rpc_method_caller(RPC *this_ptr, Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 168 (static_cast<T*>(this_ptr)->*member)(arguments, result);
mbed_official 0:efe8172b4113 169 }
mbed_official 0:efe8172b4113 170
mbed_official 0:efe8172b4113 171 /* Function rpc_method_caller
mbed_official 0:efe8172b4113 172 */
mbed_official 0:efe8172b4113 173 template<class T, void(T::*member)()>
mbed_official 0:efe8172b4113 174 void rpc_method_caller(RPC *this_ptr, Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 175 (static_cast<T*>(this_ptr)->*member)();
mbed_official 0:efe8172b4113 176 }
mbed_official 0:efe8172b4113 177
mbed_official 0:efe8172b4113 178 /* Function rpc_method_caller
mbed_official 0:efe8172b4113 179 */
mbed_official 0:efe8172b4113 180 template<class T, typename A1, void(T::*member)(A1)>
mbed_official 0:efe8172b4113 181 void rpc_method_caller(RPC *this_ptr, Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 182 A1 arg1 = arguments->getArg<A1>();
emilmont 1:6919289a5946 183
mbed_official 0:efe8172b4113 184 (static_cast<T*>(this_ptr)->*member)(arg1);
mbed_official 0:efe8172b4113 185 }
mbed_official 0:efe8172b4113 186
mbed_official 0:efe8172b4113 187 /* Function rpc_method_caller
mbed_official 0:efe8172b4113 188 */
mbed_official 0:efe8172b4113 189 template<class T, typename A1, typename A2, void(T::*member)(A1, A2)>
mbed_official 0:efe8172b4113 190 void rpc_method_caller(RPC *this_ptr, Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 191 A1 arg1 = arguments->getArg<A1>();
mbed_official 0:efe8172b4113 192 A2 arg2 = arguments->getArg<A2>();
emilmont 1:6919289a5946 193
mbed_official 0:efe8172b4113 194 (static_cast<T*>(this_ptr)->*member)(arg1, arg2);
mbed_official 0:efe8172b4113 195 }
mbed_official 0:efe8172b4113 196
mbed_official 0:efe8172b4113 197 /* Function rpc_method_caller
mbed_official 0:efe8172b4113 198 */
mbed_official 0:efe8172b4113 199 template<class T, typename A1, typename A2, typename A3, void(T::*member)(A1, A2, A3)>
mbed_official 0:efe8172b4113 200 void rpc_method_caller(RPC *this_ptr, Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 201 A1 arg1 = arguments->getArg<A1>();
mbed_official 0:efe8172b4113 202 A2 arg2 = arguments->getArg<A2>();
mbed_official 0:efe8172b4113 203 A3 arg3 = arguments->getArg<A3>();
emilmont 1:6919289a5946 204
mbed_official 0:efe8172b4113 205 (static_cast<T*>(this_ptr)->*member)(arg1, arg2, arg3);
mbed_official 0:efe8172b4113 206 }
mbed_official 0:efe8172b4113 207
mbed_official 0:efe8172b4113 208 /* Function rpc_method_caller
mbed_official 0:efe8172b4113 209 */
mbed_official 0:efe8172b4113 210 template<typename R, class T, R(T::*member)()>
mbed_official 0:efe8172b4113 211 void rpc_method_caller(RPC *this_ptr, Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 212 R res = (static_cast<T*>(this_ptr)->*member)();
mbed_official 0:efe8172b4113 213 result->putData<R>(res);
mbed_official 0:efe8172b4113 214 }
mbed_official 0:efe8172b4113 215
mbed_official 0:efe8172b4113 216 /* Function rpc_method_caller
mbed_official 0:efe8172b4113 217 */
mbed_official 0:efe8172b4113 218 template<typename R, class T, typename A1, R(T::*member)(A1)>
mbed_official 0:efe8172b4113 219 void rpc_method_caller(RPC *this_ptr, Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 220 A1 arg1 = arguments->getArg<A1>();
emilmont 1:6919289a5946 221
mbed_official 0:efe8172b4113 222 R res = (static_cast<T*>(this_ptr)->*member)(arg1);
mbed_official 0:efe8172b4113 223 result->putData<R>(res);
mbed_official 0:efe8172b4113 224 }
mbed_official 0:efe8172b4113 225
mbed_official 0:efe8172b4113 226 /* Function rpc_method_caller
mbed_official 0:efe8172b4113 227 */
mbed_official 0:efe8172b4113 228 template<typename R, class T, typename A1, typename A2, R(T::*member)(A1, A2)>
mbed_official 0:efe8172b4113 229 void rpc_method_caller(RPC *this_ptr, Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 230 A1 arg1 = arguments->getArg<A1>();
mbed_official 0:efe8172b4113 231 A2 arg2 = arguments->getArg<A2>();
emilmont 1:6919289a5946 232
mbed_official 0:efe8172b4113 233 R res = (static_cast<T*>(this_ptr)->*member)(arg1, arg2);
mbed_official 0:efe8172b4113 234 result->putData<R>(res);
mbed_official 0:efe8172b4113 235 }
mbed_official 0:efe8172b4113 236
mbed_official 0:efe8172b4113 237 /* Function rpc_method_caller
mbed_official 0:efe8172b4113 238 */
mbed_official 0:efe8172b4113 239 template<typename R, class T, typename A1, typename A2, typename A3, R(T::*member)(A1, A2, A3)>
mbed_official 0:efe8172b4113 240 void rpc_method_caller(RPC *this_ptr, Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 241 A1 arg1 = arguments->getArg<A1>();
mbed_official 0:efe8172b4113 242 A2 arg2 = arguments->getArg<A2>();
mbed_official 0:efe8172b4113 243 A3 arg3 = arguments->getArg<A3>();
emilmont 1:6919289a5946 244
mbed_official 0:efe8172b4113 245 R res = (static_cast<T*>(this_ptr)->*member)(arg1, arg2, arg3);
mbed_official 0:efe8172b4113 246 result->putData<R>(res);
mbed_official 0:efe8172b4113 247 }
mbed_official 0:efe8172b4113 248
mbed_official 0:efe8172b4113 249 /* Function rpc_function caller
mbed_official 0:efe8172b4113 250 */
mbed_official 0:efe8172b4113 251 template<typename R, R(*func)()>
mbed_official 0:efe8172b4113 252 void rpc_function_caller(Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 253 R res = (*func)();
mbed_official 0:efe8172b4113 254 result->putData<R>(res);
mbed_official 0:efe8172b4113 255 }
mbed_official 0:efe8172b4113 256
mbed_official 0:efe8172b4113 257 /* Function rpc_function caller
mbed_official 0:efe8172b4113 258 */
mbed_official 0:efe8172b4113 259 template<typename R, typename A1, R(*func)(A1)>
mbed_official 0:efe8172b4113 260 void rpc_function_caller(Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 261 A1 arg1 = arguments->getArg<A1>();
mbed_official 0:efe8172b4113 262 R res = (*func)(arg1);
mbed_official 0:efe8172b4113 263 result->putData<R>(res);
mbed_official 0:efe8172b4113 264 }
mbed_official 0:efe8172b4113 265
mbed_official 0:efe8172b4113 266 /* Function rpc_function caller
mbed_official 0:efe8172b4113 267 */
mbed_official 0:efe8172b4113 268 template<typename R, typename A1, typename A2, R(*func)(A1, A2)>
mbed_official 0:efe8172b4113 269 void rpc_function_caller(Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 270 A1 arg1 = arguments->getArg<A1>();
mbed_official 0:efe8172b4113 271 A2 arg2 = arguments->getArg<A2>();
emilmont 1:6919289a5946 272
mbed_official 0:efe8172b4113 273 R res = (*func)(arg1, arg2);
mbed_official 0:efe8172b4113 274 result->putData<R>(res);
mbed_official 0:efe8172b4113 275 }
mbed_official 0:efe8172b4113 276
mbed_official 0:efe8172b4113 277 /* Function rpc_function caller
mbed_official 0:efe8172b4113 278 */
mbed_official 0:efe8172b4113 279 template<typename R, typename A1, typename A2, typename A3, R(*func)(A1, A2, A3)>
mbed_official 0:efe8172b4113 280 void rpc_function_caller(Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 281 A1 arg1 = arguments->getArg<A1>();
mbed_official 0:efe8172b4113 282 A2 arg2 = arguments->getArg<A2>();
mbed_official 0:efe8172b4113 283 A3 arg3 = arguments->getArg<A3>();
emilmont 1:6919289a5946 284
mbed_official 0:efe8172b4113 285 R res = (*func)(arg1, arg2, arg3);
mbed_official 0:efe8172b4113 286 result->putData<R>(res);
mbed_official 0:efe8172b4113 287 }
mbed_official 0:efe8172b4113 288
mbed_official 0:efe8172b4113 289 /* Function rpc_function caller
mbed_official 0:efe8172b4113 290 */
mbed_official 0:efe8172b4113 291 template<typename R, typename A1, typename A2, typename A3, typename A4, R(*func)(A1, A2, A3, A4)>
mbed_official 0:efe8172b4113 292 void rpc_function_caller(Arguments *arguments, Reply *result) {
mbed_official 0:efe8172b4113 293 A1 arg1 = arguments->getArg<A1>();
mbed_official 0:efe8172b4113 294 A2 arg2 = arguments->getArg<A2>();
mbed_official 0:efe8172b4113 295 A3 arg3 = arguments->getArg<A3>();
mbed_official 0:efe8172b4113 296 A4 arg4 = arguments->getArg<A4>();
emilmont 1:6919289a5946 297
mbed_official 0:efe8172b4113 298 R res = (*func)(arg1, arg2, arg3, arg4);
mbed_official 0:efe8172b4113 299 result->putData<R>(res);
mbed_official 0:efe8172b4113 300 }
mbed_official 0:efe8172b4113 301
mbed_official 0:efe8172b4113 302 struct rpc_method {
mbed_official 0:efe8172b4113 303 const char *name;
mbed_official 0:efe8172b4113 304 typedef void (*method_caller_t)(RPC*, Arguments*, Reply*);
mbed_official 0:efe8172b4113 305 typedef const struct rpc_method *(*super_t)(RPC*);
mbed_official 0:efe8172b4113 306 union {
mbed_official 0:efe8172b4113 307 method_caller_t method_caller;
mbed_official 0:efe8172b4113 308 super_t super;
mbed_official 0:efe8172b4113 309 };
mbed_official 0:efe8172b4113 310 };
mbed_official 0:efe8172b4113 311
mbed_official 0:efe8172b4113 312 template<class C>
mbed_official 0:efe8172b4113 313 const struct rpc_method *rpc_super(RPC *this_ptr) {
mbed_official 0:efe8172b4113 314 return static_cast<C*>(this_ptr)->C::get_rpc_methods();
mbed_official 0:efe8172b4113 315 }
mbed_official 0:efe8172b4113 316
mbed_official 0:efe8172b4113 317 #define RPC_METHOD_END { NULL, NULL }
mbed_official 0:efe8172b4113 318 #define RPC_METHOD_SUPER(C) { NULL, (rpc_method::method_caller_t)rpc_super<C> }
mbed_official 0:efe8172b4113 319
mbed_official 0:efe8172b4113 320 } // namespace mbed
mbed_official 0:efe8172b4113 321
mbed_official 0:efe8172b4113 322 #endif