mbed RPC

Dependents:   WiFlyHTTPServerSample MultiThreadingHTTPServer HTTP-Server EthHTTPServer ... more

Legacy Warning

This is an mbed 2 library. To learn more about mbed OS 5, visit the docs.

Committer:
mbed_official
Date:
Mon Apr 11 17:30:17 2016 +0100
Revision:
14:188b1505f827
Parent:
10:d3e03663a6f4
Synchronized with git revision 02b197ca163ddbf6702c130b1799975caaf87841

Full URL: https://github.com/mbedmicro/mbed/commit/02b197ca163ddbf6702c130b1799975caaf87841/

The RPC call appended the method name to the output after the method
had already finished processing. It was unexpected for my use case,
and doesn't feel like the obvious thing to do. This could be appended
in the RPC method itself, instead.

The adding of the method to the output was first commited in commit
556b889b5ff64126eb430aa8326e8bce0b451100.

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 #include "rpc.h"
mbed_official 0:efe8172b4113 17
mbed_official 0:efe8172b4113 18 using namespace std;
mbed_official 0:efe8172b4113 19
mbed_official 0:efe8172b4113 20 namespace mbed {
mbed_official 0:efe8172b4113 21
mbed_official 0:efe8172b4113 22 RPC::RPC(const char *name) {
mbed_official 0:efe8172b4113 23 _from_construct = false;
mbed_official 0:efe8172b4113 24 if (name != NULL) {
mbed_official 0:efe8172b4113 25 _name = new char[strlen(name) + 1];
mbed_official 0:efe8172b4113 26 strcpy(_name, name);
mbed_official 0:efe8172b4113 27 } else {
mbed_official 0:efe8172b4113 28 _name = new char[12];
mbed_official 0:efe8172b4113 29 sprintf(_name, "obj%p", this);
mbed_official 0:efe8172b4113 30 }
mbed_official 0:efe8172b4113 31 // put this object at head of the list
mbed_official 0:efe8172b4113 32 _next = _head;
mbed_official 0:efe8172b4113 33 _head = this;
mbed_official 0:efe8172b4113 34 }
mbed_official 0:efe8172b4113 35
mbed_official 0:efe8172b4113 36 RPC::~RPC() {
mbed_official 0:efe8172b4113 37 // remove this object from the list
mbed_official 0:efe8172b4113 38 if (_head == this) { // first in the list, so just drop me
mbed_official 0:efe8172b4113 39 _head = _next;
mbed_official 0:efe8172b4113 40 } else { // find the object before me, then drop me
mbed_official 0:efe8172b4113 41 RPC* p = _head;
mbed_official 0:efe8172b4113 42 while (p->_next != this) {
mbed_official 0:efe8172b4113 43 p = p->_next;
mbed_official 0:efe8172b4113 44 }
mbed_official 0:efe8172b4113 45 p->_next = _next;
mbed_official 0:efe8172b4113 46 }
mbed_official 0:efe8172b4113 47 }
mbed_official 0:efe8172b4113 48
mbed_official 0:efe8172b4113 49 const rpc_method *RPC::get_rpc_methods() {
mbed_official 0:efe8172b4113 50 static const rpc_method methods[] = {
mbed_official 0:efe8172b4113 51 {"delete", rpc_method_caller<RPC, &RPC::delete_self> },
mbed_official 0:efe8172b4113 52 RPC_METHOD_END
mbed_official 0:efe8172b4113 53 };
mbed_official 0:efe8172b4113 54 return methods;
mbed_official 0:efe8172b4113 55 }
mbed_official 0:efe8172b4113 56
mbed_official 0:efe8172b4113 57 RPC *RPC::lookup(const char *name) {
mbed_official 0:efe8172b4113 58 size_t len = strlen(name);
mbed_official 0:efe8172b4113 59 for (RPC *p = _head; p != NULL; p = p->_next) {
mbed_official 0:efe8172b4113 60 /* Check that p->_name matches name and is the correct length */
mbed_official 0:efe8172b4113 61 if (strncmp(p->_name, name, len) == 0 && (strlen(p->_name) == len)) {
mbed_official 0:efe8172b4113 62 return p;
mbed_official 0:efe8172b4113 63 }
mbed_official 0:efe8172b4113 64 }
mbed_official 0:efe8172b4113 65 return NULL;
mbed_official 0:efe8172b4113 66 }
mbed_official 0:efe8172b4113 67
mbed_official 0:efe8172b4113 68 void RPC::delete_self() {
mbed_official 0:efe8172b4113 69 delete[] _name;
mbed_official 0:efe8172b4113 70 if (_from_construct) {
mbed_official 0:efe8172b4113 71 delete this;
mbed_official 0:efe8172b4113 72 }
mbed_official 0:efe8172b4113 73 }
mbed_official 0:efe8172b4113 74
mbed_official 0:efe8172b4113 75 void RPC::list_objs(Arguments *args, Reply *result) {
mbed_official 0:efe8172b4113 76 for (RPC *ptr = RPC::_head; ptr != NULL; ptr = ptr->_next) {
mbed_official 0:efe8172b4113 77 if (ptr->_from_construct) {
mbed_official 0:efe8172b4113 78 result->putData<const char*>(ptr->_name);
mbed_official 0:efe8172b4113 79 }
mbed_official 0:efe8172b4113 80 }
mbed_official 0:efe8172b4113 81 }
mbed_official 0:efe8172b4113 82
mbed_official 0:efe8172b4113 83 void RPC::clear(Arguments*, Reply*) {
mbed_official 0:efe8172b4113 84 RPC *ptr = RPC::_head;
mbed_official 0:efe8172b4113 85 while (ptr != NULL) {
mbed_official 0:efe8172b4113 86 RPC *tmp = ptr;
mbed_official 0:efe8172b4113 87 ptr = ptr->_next;
mbed_official 0:efe8172b4113 88 delete[] tmp->_name;
mbed_official 0:efe8172b4113 89 if (tmp->_from_construct) {
mbed_official 0:efe8172b4113 90 delete tmp;
mbed_official 0:efe8172b4113 91 }
mbed_official 0:efe8172b4113 92 }
mbed_official 0:efe8172b4113 93 }
mbed_official 0:efe8172b4113 94
mbed_official 0:efe8172b4113 95 const rpc_function RPC::_RPC_funcs[] = {
mbed_official 0:efe8172b4113 96 {"clear", &RPC::clear },
mbed_official 0:efe8172b4113 97 { "objects", &RPC::list_objs },
mbed_official 0:efe8172b4113 98 RPC_METHOD_END
mbed_official 0:efe8172b4113 99 };
mbed_official 0:efe8172b4113 100
mbed_official 0:efe8172b4113 101 rpc_class RPC::_RPC_class = { "RPC", _RPC_funcs, NULL };
mbed_official 0:efe8172b4113 102
mbed_official 0:efe8172b4113 103 RPC *RPC::_head = NULL;
mbed_official 0:efe8172b4113 104
mbed_official 0:efe8172b4113 105 rpc_class *RPC::_classes = &_RPC_class;
mbed_official 0:efe8172b4113 106
mbed_official 0:efe8172b4113 107 bool RPC::call(const char *request, char *reply) {
mbed_official 0:efe8172b4113 108 if (request == NULL) return false;
emilmont 1:6919289a5946 109
mbed_official 0:efe8172b4113 110 Arguments args(request);
mbed_official 0:efe8172b4113 111 Reply r(reply);
emilmont 1:6919289a5946 112
mbed_official 0:efe8172b4113 113 /* If there's no name print object and class names to result */
mbed_official 0:efe8172b4113 114 if (args.obj_name == NULL) {
mbed_official 0:efe8172b4113 115 for (RPC *p = RPC::_head; p != NULL; p = p->_next) {
mbed_official 0:efe8172b4113 116 r.putData<const char*>(p->_name);
mbed_official 0:efe8172b4113 117 }
mbed_official 0:efe8172b4113 118 for (rpc_class *c = RPC::_classes; c != NULL; c = c->next) {
mbed_official 0:efe8172b4113 119 r.putData<const char*>(c->name);
mbed_official 0:efe8172b4113 120 }
mbed_official 0:efe8172b4113 121 return true;
mbed_official 0:efe8172b4113 122 }
emilmont 1:6919289a5946 123
mbed_official 0:efe8172b4113 124 /* First try matching an instance */
mbed_official 0:efe8172b4113 125 RPC *p = lookup(args.obj_name);
mbed_official 0:efe8172b4113 126 if (p != NULL) {
mbed_official 0:efe8172b4113 127 /* Get the list of methods we support */
mbed_official 0:efe8172b4113 128 const rpc_method *cur_method = p->get_rpc_methods();
emilmont 1:6919289a5946 129
mbed_official 0:efe8172b4113 130 /* When there's no method print method names to result */
mbed_official 0:efe8172b4113 131 if (args.method_name == NULL) {
mbed_official 0:efe8172b4113 132 while (true) {
mbed_official 0:efe8172b4113 133 for (; cur_method->name != NULL; cur_method++) {
mbed_official 0:efe8172b4113 134 r.putData<const char*>(cur_method->name);
mbed_official 0:efe8172b4113 135 }
emilmont 1:6919289a5946 136
mbed_official 0:efe8172b4113 137 /* write_name_arr's args are references, so result and cur_method will have changed */
mbed_official 0:efe8172b4113 138 if (cur_method->super != 0) {
mbed_official 0:efe8172b4113 139 cur_method = cur_method->super(p);
mbed_official 0:efe8172b4113 140 } else {
mbed_official 0:efe8172b4113 141 return true;
mbed_official 0:efe8172b4113 142 }
mbed_official 0:efe8172b4113 143 }
mbed_official 0:efe8172b4113 144 }
emilmont 1:6919289a5946 145
mbed_official 0:efe8172b4113 146 /* Look through the methods for the one whose name matches */
mbed_official 0:efe8172b4113 147 while (true) {
mbed_official 0:efe8172b4113 148 for (; cur_method->name != NULL; cur_method++) {
mbed_official 0:efe8172b4113 149 if (strcmp(cur_method->name, args.method_name) == 0) {
mbed_official 0:efe8172b4113 150 (cur_method->method_caller)(p, &args, &r);
mbed_official 0:efe8172b4113 151 return true;
mbed_official 0:efe8172b4113 152 }
mbed_official 0:efe8172b4113 153 }
emilmont 1:6919289a5946 154
mbed_official 0:efe8172b4113 155 if (cur_method->super != 0) {
mbed_official 0:efe8172b4113 156 cur_method = cur_method->super(p);
mbed_official 0:efe8172b4113 157 } else {
mbed_official 0:efe8172b4113 158 /* end of methods and no match */
mbed_official 0:efe8172b4113 159 return false;
mbed_official 0:efe8172b4113 160 }
emilmont 1:6919289a5946 161
mbed_official 0:efe8172b4113 162 }
mbed_official 0:efe8172b4113 163 }
emilmont 1:6919289a5946 164
mbed_official 0:efe8172b4113 165 /* Then try a class */
mbed_official 0:efe8172b4113 166 for (const rpc_class *q = _classes; q != NULL; q = q->next) {
mbed_official 0:efe8172b4113 167 if (strcmp(q->name, args.obj_name) == 0) {
mbed_official 0:efe8172b4113 168 /* Matched the class name, so get its functions */
mbed_official 0:efe8172b4113 169 const rpc_function *cur_func = q->static_functions;
mbed_official 0:efe8172b4113 170 if (args.method_name == NULL) {
mbed_official 0:efe8172b4113 171 for (; cur_func->name != NULL; cur_func++) {
mbed_official 0:efe8172b4113 172 r.putData<const char*>(cur_func->name);
mbed_official 0:efe8172b4113 173 }
mbed_official 0:efe8172b4113 174 return true;
mbed_official 0:efe8172b4113 175 } else {
mbed_official 0:efe8172b4113 176 /* Otherwise call the appropriate function */
mbed_official 0:efe8172b4113 177 for (; cur_func->name != NULL; cur_func++) {
mbed_official 0:efe8172b4113 178 if (strcmp(cur_func->name, args.method_name) == 0) {
mbed_official 0:efe8172b4113 179 (cur_func->function_caller)(&args, &r);
mbed_official 0:efe8172b4113 180 return true;
mbed_official 0:efe8172b4113 181 }
mbed_official 0:efe8172b4113 182 }
mbed_official 0:efe8172b4113 183 return false;
mbed_official 0:efe8172b4113 184 }
mbed_official 0:efe8172b4113 185 }
mbed_official 0:efe8172b4113 186 }
emilmont 1:6919289a5946 187
mbed_official 0:efe8172b4113 188 return false;
mbed_official 0:efe8172b4113 189 }
mbed_official 0:efe8172b4113 190
mbed_official 0:efe8172b4113 191 } // namespace mbed