TX1 node

Committer:
mbed_official
Date:
Tue Nov 20 17:23:59 2012 +0000
Revision:
0:efe8172b4113
Child:
1:6919289a5946
mbed RPC

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:efe8172b4113 1 /* mbed Microcontroller Library
mbed_official 0:efe8172b4113 2 * Copyright (c) 2006-2012 ARM Limited
mbed_official 0:efe8172b4113 3 *
mbed_official 0:efe8172b4113 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
mbed_official 0:efe8172b4113 5 * of this software and associated documentation files (the "Software"), to deal
mbed_official 0:efe8172b4113 6 * in the Software without restriction, including without limitation the rights
mbed_official 0:efe8172b4113 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
mbed_official 0:efe8172b4113 8 * copies of the Software, and to permit persons to whom the Software is
mbed_official 0:efe8172b4113 9 * furnished to do so, subject to the following conditions:
mbed_official 0:efe8172b4113 10 *
mbed_official 0:efe8172b4113 11 * The above copyright notice and this permission notice shall be included in
mbed_official 0:efe8172b4113 12 * all copies or substantial portions of the Software.
mbed_official 0:efe8172b4113 13 *
mbed_official 0:efe8172b4113 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
mbed_official 0:efe8172b4113 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
mbed_official 0:efe8172b4113 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
mbed_official 0:efe8172b4113 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
mbed_official 0:efe8172b4113 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
mbed_official 0:efe8172b4113 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
mbed_official 0:efe8172b4113 20 * SOFTWARE.
mbed_official 0:efe8172b4113 21 */
mbed_official 0:efe8172b4113 22 #include "rpc.h"
mbed_official 0:efe8172b4113 23
mbed_official 0:efe8172b4113 24 using namespace std;
mbed_official 0:efe8172b4113 25
mbed_official 0:efe8172b4113 26 namespace mbed {
mbed_official 0:efe8172b4113 27
mbed_official 0:efe8172b4113 28 RPC::RPC(const char *name) {
mbed_official 0:efe8172b4113 29 _from_construct = false;
mbed_official 0:efe8172b4113 30 if (name != NULL) {
mbed_official 0:efe8172b4113 31 _name = new char[strlen(name) + 1];
mbed_official 0:efe8172b4113 32 strcpy(_name, name);
mbed_official 0:efe8172b4113 33 } else {
mbed_official 0:efe8172b4113 34 _name = new char[12];
mbed_official 0:efe8172b4113 35 sprintf(_name, "obj%p", this);
mbed_official 0:efe8172b4113 36 }
mbed_official 0:efe8172b4113 37 // put this object at head of the list
mbed_official 0:efe8172b4113 38 _next = _head;
mbed_official 0:efe8172b4113 39 _head = this;
mbed_official 0:efe8172b4113 40 }
mbed_official 0:efe8172b4113 41
mbed_official 0:efe8172b4113 42 RPC::~RPC() {
mbed_official 0:efe8172b4113 43 // remove this object from the list
mbed_official 0:efe8172b4113 44 if (_head == this) { // first in the list, so just drop me
mbed_official 0:efe8172b4113 45 _head = _next;
mbed_official 0:efe8172b4113 46 } else { // find the object before me, then drop me
mbed_official 0:efe8172b4113 47 RPC* p = _head;
mbed_official 0:efe8172b4113 48 while (p->_next != this) {
mbed_official 0:efe8172b4113 49 p = p->_next;
mbed_official 0:efe8172b4113 50 }
mbed_official 0:efe8172b4113 51 p->_next = _next;
mbed_official 0:efe8172b4113 52 }
mbed_official 0:efe8172b4113 53 }
mbed_official 0:efe8172b4113 54
mbed_official 0:efe8172b4113 55 const rpc_method *RPC::get_rpc_methods() {
mbed_official 0:efe8172b4113 56 static const rpc_method methods[] = {
mbed_official 0:efe8172b4113 57 {"delete", rpc_method_caller<RPC, &RPC::delete_self> },
mbed_official 0:efe8172b4113 58 RPC_METHOD_END
mbed_official 0:efe8172b4113 59 };
mbed_official 0:efe8172b4113 60 return methods;
mbed_official 0:efe8172b4113 61 }
mbed_official 0:efe8172b4113 62
mbed_official 0:efe8172b4113 63 RPC *RPC::lookup(const char *name) {
mbed_official 0:efe8172b4113 64 size_t len = strlen(name);
mbed_official 0:efe8172b4113 65 for (RPC *p = _head; p != NULL; p = p->_next) {
mbed_official 0:efe8172b4113 66 /* Check that p->_name matches name and is the correct length */
mbed_official 0:efe8172b4113 67 if (strncmp(p->_name, name, len) == 0 && (strlen(p->_name) == len)) {
mbed_official 0:efe8172b4113 68 return p;
mbed_official 0:efe8172b4113 69 }
mbed_official 0:efe8172b4113 70 }
mbed_official 0:efe8172b4113 71 return NULL;
mbed_official 0:efe8172b4113 72 }
mbed_official 0:efe8172b4113 73
mbed_official 0:efe8172b4113 74 void RPC::delete_self() {
mbed_official 0:efe8172b4113 75 delete[] _name;
mbed_official 0:efe8172b4113 76 if (_from_construct) {
mbed_official 0:efe8172b4113 77 delete this;
mbed_official 0:efe8172b4113 78 }
mbed_official 0:efe8172b4113 79 }
mbed_official 0:efe8172b4113 80
mbed_official 0:efe8172b4113 81 void RPC::list_objs(Arguments *args, Reply *result) {
mbed_official 0:efe8172b4113 82 for (RPC *ptr = RPC::_head; ptr != NULL; ptr = ptr->_next) {
mbed_official 0:efe8172b4113 83 if (ptr->_from_construct) {
mbed_official 0:efe8172b4113 84 result->putData<const char*>(ptr->_name);
mbed_official 0:efe8172b4113 85 }
mbed_official 0:efe8172b4113 86 }
mbed_official 0:efe8172b4113 87 }
mbed_official 0:efe8172b4113 88
mbed_official 0:efe8172b4113 89 void RPC::clear(Arguments*, Reply*) {
mbed_official 0:efe8172b4113 90 RPC *ptr = RPC::_head;
mbed_official 0:efe8172b4113 91 while (ptr != NULL) {
mbed_official 0:efe8172b4113 92 RPC *tmp = ptr;
mbed_official 0:efe8172b4113 93 ptr = ptr->_next;
mbed_official 0:efe8172b4113 94 delete[] tmp->_name;
mbed_official 0:efe8172b4113 95 if (tmp->_from_construct) {
mbed_official 0:efe8172b4113 96 delete tmp;
mbed_official 0:efe8172b4113 97 }
mbed_official 0:efe8172b4113 98 }
mbed_official 0:efe8172b4113 99 }
mbed_official 0:efe8172b4113 100
mbed_official 0:efe8172b4113 101 const rpc_function RPC::_RPC_funcs[] = {
mbed_official 0:efe8172b4113 102 {"clear", &RPC::clear },
mbed_official 0:efe8172b4113 103 { "objects", &RPC::list_objs },
mbed_official 0:efe8172b4113 104 RPC_METHOD_END
mbed_official 0:efe8172b4113 105 };
mbed_official 0:efe8172b4113 106
mbed_official 0:efe8172b4113 107 rpc_class RPC::_RPC_class = { "RPC", _RPC_funcs, NULL };
mbed_official 0:efe8172b4113 108
mbed_official 0:efe8172b4113 109 RPC *RPC::_head = NULL;
mbed_official 0:efe8172b4113 110
mbed_official 0:efe8172b4113 111 rpc_class *RPC::_classes = &_RPC_class;
mbed_official 0:efe8172b4113 112
mbed_official 0:efe8172b4113 113 bool RPC::call(const char *request, char *reply) {
mbed_official 0:efe8172b4113 114 if (request == NULL) return false;
mbed_official 0:efe8172b4113 115
mbed_official 0:efe8172b4113 116 Arguments args(request);
mbed_official 0:efe8172b4113 117 Reply r(reply);
mbed_official 0:efe8172b4113 118
mbed_official 0:efe8172b4113 119 /* If there's no name print object and class names to result */
mbed_official 0:efe8172b4113 120 if (args.obj_name == NULL) {
mbed_official 0:efe8172b4113 121 for (RPC *p = RPC::_head; p != NULL; p = p->_next) {
mbed_official 0:efe8172b4113 122 r.putData<const char*>(p->_name);
mbed_official 0:efe8172b4113 123 }
mbed_official 0:efe8172b4113 124 for (rpc_class *c = RPC::_classes; c != NULL; c = c->next) {
mbed_official 0:efe8172b4113 125 r.putData<const char*>(c->name);
mbed_official 0:efe8172b4113 126 }
mbed_official 0:efe8172b4113 127 return true;
mbed_official 0:efe8172b4113 128 }
mbed_official 0:efe8172b4113 129
mbed_official 0:efe8172b4113 130 /* First try matching an instance */
mbed_official 0:efe8172b4113 131 RPC *p = lookup(args.obj_name);
mbed_official 0:efe8172b4113 132 if (p != NULL) {
mbed_official 0:efe8172b4113 133 /* Get the list of methods we support */
mbed_official 0:efe8172b4113 134 const rpc_method *cur_method = p->get_rpc_methods();
mbed_official 0:efe8172b4113 135
mbed_official 0:efe8172b4113 136 /* When there's no method print method names to result */
mbed_official 0:efe8172b4113 137 if (args.method_name == NULL) {
mbed_official 0:efe8172b4113 138 while (true) {
mbed_official 0:efe8172b4113 139 for (; cur_method->name != NULL; cur_method++) {
mbed_official 0:efe8172b4113 140 r.putData<const char*>(cur_method->name);
mbed_official 0:efe8172b4113 141 }
mbed_official 0:efe8172b4113 142
mbed_official 0:efe8172b4113 143 /* write_name_arr's args are references, so result and cur_method will have changed */
mbed_official 0:efe8172b4113 144 if (cur_method->super != 0) {
mbed_official 0:efe8172b4113 145 cur_method = cur_method->super(p);
mbed_official 0:efe8172b4113 146 } else {
mbed_official 0:efe8172b4113 147 return true;
mbed_official 0:efe8172b4113 148 }
mbed_official 0:efe8172b4113 149 }
mbed_official 0:efe8172b4113 150 }
mbed_official 0:efe8172b4113 151
mbed_official 0:efe8172b4113 152 /* Look through the methods for the one whose name matches */
mbed_official 0:efe8172b4113 153 while (true) {
mbed_official 0:efe8172b4113 154 for (; cur_method->name != NULL; cur_method++) {
mbed_official 0:efe8172b4113 155 if (strcmp(cur_method->name, args.method_name) == 0) {
mbed_official 0:efe8172b4113 156 (cur_method->method_caller)(p, &args, &r);
mbed_official 0:efe8172b4113 157 return true;
mbed_official 0:efe8172b4113 158 }
mbed_official 0:efe8172b4113 159 }
mbed_official 0:efe8172b4113 160
mbed_official 0:efe8172b4113 161 if (cur_method->super != 0) {
mbed_official 0:efe8172b4113 162 cur_method = cur_method->super(p);
mbed_official 0:efe8172b4113 163 } else {
mbed_official 0:efe8172b4113 164 /* end of methods and no match */
mbed_official 0:efe8172b4113 165 return false;
mbed_official 0:efe8172b4113 166 }
mbed_official 0:efe8172b4113 167
mbed_official 0:efe8172b4113 168 }
mbed_official 0:efe8172b4113 169 }
mbed_official 0:efe8172b4113 170
mbed_official 0:efe8172b4113 171 /* Then try a class */
mbed_official 0:efe8172b4113 172 for (const rpc_class *q = _classes; q != NULL; q = q->next) {
mbed_official 0:efe8172b4113 173 if (strcmp(q->name, args.obj_name) == 0) {
mbed_official 0:efe8172b4113 174 /* Matched the class name, so get its functions */
mbed_official 0:efe8172b4113 175 const rpc_function *cur_func = q->static_functions;
mbed_official 0:efe8172b4113 176 if (args.method_name == NULL) {
mbed_official 0:efe8172b4113 177 for (; cur_func->name != NULL; cur_func++) {
mbed_official 0:efe8172b4113 178 r.putData<const char*>(cur_func->name);
mbed_official 0:efe8172b4113 179 }
mbed_official 0:efe8172b4113 180 return true;
mbed_official 0:efe8172b4113 181 } else {
mbed_official 0:efe8172b4113 182 /* Otherwise call the appropriate function */
mbed_official 0:efe8172b4113 183 for (; cur_func->name != NULL; cur_func++) {
mbed_official 0:efe8172b4113 184 if (strcmp(cur_func->name, args.method_name) == 0) {
mbed_official 0:efe8172b4113 185 (cur_func->function_caller)(&args, &r);
mbed_official 0:efe8172b4113 186 return true;
mbed_official 0:efe8172b4113 187 }
mbed_official 0:efe8172b4113 188 }
mbed_official 0:efe8172b4113 189 return false;
mbed_official 0:efe8172b4113 190 }
mbed_official 0:efe8172b4113 191 }
mbed_official 0:efe8172b4113 192 }
mbed_official 0:efe8172b4113 193
mbed_official 0:efe8172b4113 194 return false;
mbed_official 0:efe8172b4113 195 }
mbed_official 0:efe8172b4113 196
mbed_official 0:efe8172b4113 197 } // namespace mbed