mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

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