nkjnm

Dependencies:   MAX44000 nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Committer:
nexpaq
Date:
Sat Sep 17 16:32:05 2016 +0000
Revision:
1:55a6170b404f
checking in for sharing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 1:55a6170b404f 1 /* mbed Microcontroller Library
nexpaq 1:55a6170b404f 2 * Copyright (c) 2006-2013 ARM Limited
nexpaq 1:55a6170b404f 3 *
nexpaq 1:55a6170b404f 4 * Licensed under the Apache License, Version 2.0 (the "License");
nexpaq 1:55a6170b404f 5 * you may not use this file except in compliance with the License.
nexpaq 1:55a6170b404f 6 * You may obtain a copy of the License at
nexpaq 1:55a6170b404f 7 *
nexpaq 1:55a6170b404f 8 * http://www.apache.org/licenses/LICENSE-2.0
nexpaq 1:55a6170b404f 9 *
nexpaq 1:55a6170b404f 10 * Unless required by applicable law or agreed to in writing, software
nexpaq 1:55a6170b404f 11 * distributed under the License is distributed on an "AS IS" BASIS,
nexpaq 1:55a6170b404f 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nexpaq 1:55a6170b404f 13 * See the License for the specific language governing permissions and
nexpaq 1:55a6170b404f 14 * limitations under the License.
nexpaq 1:55a6170b404f 15 */
nexpaq 1:55a6170b404f 16 #include "rpc.h"
nexpaq 1:55a6170b404f 17
nexpaq 1:55a6170b404f 18 using namespace std;
nexpaq 1:55a6170b404f 19
nexpaq 1:55a6170b404f 20 namespace mbed {
nexpaq 1:55a6170b404f 21
nexpaq 1:55a6170b404f 22 RPC::RPC(const char *name) {
nexpaq 1:55a6170b404f 23 _from_construct = false;
nexpaq 1:55a6170b404f 24 if (name != NULL) {
nexpaq 1:55a6170b404f 25 _name = new char[strlen(name) + 1];
nexpaq 1:55a6170b404f 26 strcpy(_name, name);
nexpaq 1:55a6170b404f 27 } else {
nexpaq 1:55a6170b404f 28 _name = new char[12];
nexpaq 1:55a6170b404f 29 sprintf(_name, "obj%p", this);
nexpaq 1:55a6170b404f 30 }
nexpaq 1:55a6170b404f 31 // put this object at head of the list
nexpaq 1:55a6170b404f 32 _next = _head;
nexpaq 1:55a6170b404f 33 _head = this;
nexpaq 1:55a6170b404f 34 }
nexpaq 1:55a6170b404f 35
nexpaq 1:55a6170b404f 36 RPC::~RPC() {
nexpaq 1:55a6170b404f 37 // remove this object from the list
nexpaq 1:55a6170b404f 38 if (_head == this) { // first in the list, so just drop me
nexpaq 1:55a6170b404f 39 _head = _next;
nexpaq 1:55a6170b404f 40 } else { // find the object before me, then drop me
nexpaq 1:55a6170b404f 41 RPC* p = _head;
nexpaq 1:55a6170b404f 42 while (p->_next != this) {
nexpaq 1:55a6170b404f 43 p = p->_next;
nexpaq 1:55a6170b404f 44 }
nexpaq 1:55a6170b404f 45 p->_next = _next;
nexpaq 1:55a6170b404f 46 }
nexpaq 1:55a6170b404f 47 }
nexpaq 1:55a6170b404f 48
nexpaq 1:55a6170b404f 49 const rpc_method *RPC::get_rpc_methods() {
nexpaq 1:55a6170b404f 50 static const rpc_method methods[] = {
nexpaq 1:55a6170b404f 51 {"delete", rpc_method_caller<RPC, &RPC::delete_self> },
nexpaq 1:55a6170b404f 52 RPC_METHOD_END
nexpaq 1:55a6170b404f 53 };
nexpaq 1:55a6170b404f 54 return methods;
nexpaq 1:55a6170b404f 55 }
nexpaq 1:55a6170b404f 56
nexpaq 1:55a6170b404f 57 RPC *RPC::lookup(const char *name) {
nexpaq 1:55a6170b404f 58 size_t len = strlen(name);
nexpaq 1:55a6170b404f 59 for (RPC *p = _head; p != NULL; p = p->_next) {
nexpaq 1:55a6170b404f 60 /* Check that p->_name matches name and is the correct length */
nexpaq 1:55a6170b404f 61 if (strncmp(p->_name, name, len) == 0 && (strlen(p->_name) == len)) {
nexpaq 1:55a6170b404f 62 return p;
nexpaq 1:55a6170b404f 63 }
nexpaq 1:55a6170b404f 64 }
nexpaq 1:55a6170b404f 65 return NULL;
nexpaq 1:55a6170b404f 66 }
nexpaq 1:55a6170b404f 67
nexpaq 1:55a6170b404f 68 void RPC::delete_self() {
nexpaq 1:55a6170b404f 69 delete[] _name;
nexpaq 1:55a6170b404f 70 if (_from_construct) {
nexpaq 1:55a6170b404f 71 delete this;
nexpaq 1:55a6170b404f 72 }
nexpaq 1:55a6170b404f 73 }
nexpaq 1:55a6170b404f 74
nexpaq 1:55a6170b404f 75 void RPC::list_objs(Arguments *args, Reply *result) {
nexpaq 1:55a6170b404f 76 for (RPC *ptr = RPC::_head; ptr != NULL; ptr = ptr->_next) {
nexpaq 1:55a6170b404f 77 if (ptr->_from_construct) {
nexpaq 1:55a6170b404f 78 result->putData<const char*>(ptr->_name);
nexpaq 1:55a6170b404f 79 }
nexpaq 1:55a6170b404f 80 }
nexpaq 1:55a6170b404f 81 }
nexpaq 1:55a6170b404f 82
nexpaq 1:55a6170b404f 83 void RPC::clear(Arguments*, Reply*) {
nexpaq 1:55a6170b404f 84 RPC *ptr = RPC::_head;
nexpaq 1:55a6170b404f 85 while (ptr != NULL) {
nexpaq 1:55a6170b404f 86 RPC *tmp = ptr;
nexpaq 1:55a6170b404f 87 ptr = ptr->_next;
nexpaq 1:55a6170b404f 88 delete[] tmp->_name;
nexpaq 1:55a6170b404f 89 if (tmp->_from_construct) {
nexpaq 1:55a6170b404f 90 delete tmp;
nexpaq 1:55a6170b404f 91 }
nexpaq 1:55a6170b404f 92 }
nexpaq 1:55a6170b404f 93 }
nexpaq 1:55a6170b404f 94
nexpaq 1:55a6170b404f 95 const rpc_function RPC::_RPC_funcs[] = {
nexpaq 1:55a6170b404f 96 {"clear", &RPC::clear },
nexpaq 1:55a6170b404f 97 { "objects", &RPC::list_objs },
nexpaq 1:55a6170b404f 98 RPC_METHOD_END
nexpaq 1:55a6170b404f 99 };
nexpaq 1:55a6170b404f 100
nexpaq 1:55a6170b404f 101 rpc_class RPC::_RPC_class = { "RPC", _RPC_funcs, NULL };
nexpaq 1:55a6170b404f 102
nexpaq 1:55a6170b404f 103 RPC *RPC::_head = NULL;
nexpaq 1:55a6170b404f 104
nexpaq 1:55a6170b404f 105 rpc_class *RPC::_classes = &_RPC_class;
nexpaq 1:55a6170b404f 106
nexpaq 1:55a6170b404f 107 bool RPC::call(const char *request, char *reply) {
nexpaq 1:55a6170b404f 108 if (request == NULL) return false;
nexpaq 1:55a6170b404f 109
nexpaq 1:55a6170b404f 110 Arguments args(request);
nexpaq 1:55a6170b404f 111 Reply r(reply);
nexpaq 1:55a6170b404f 112
nexpaq 1:55a6170b404f 113 /* If there's no name print object and class names to result */
nexpaq 1:55a6170b404f 114 if (args.obj_name == NULL) {
nexpaq 1:55a6170b404f 115 for (RPC *p = RPC::_head; p != NULL; p = p->_next) {
nexpaq 1:55a6170b404f 116 r.putData<const char*>(p->_name);
nexpaq 1:55a6170b404f 117 }
nexpaq 1:55a6170b404f 118 for (rpc_class *c = RPC::_classes; c != NULL; c = c->next) {
nexpaq 1:55a6170b404f 119 r.putData<const char*>(c->name);
nexpaq 1:55a6170b404f 120 }
nexpaq 1:55a6170b404f 121 return true;
nexpaq 1:55a6170b404f 122 }
nexpaq 1:55a6170b404f 123
nexpaq 1:55a6170b404f 124 /* First try matching an instance */
nexpaq 1:55a6170b404f 125 RPC *p = lookup(args.obj_name);
nexpaq 1:55a6170b404f 126 if (p != NULL) {
nexpaq 1:55a6170b404f 127 /* Get the list of methods we support */
nexpaq 1:55a6170b404f 128 const rpc_method *cur_method = p->get_rpc_methods();
nexpaq 1:55a6170b404f 129
nexpaq 1:55a6170b404f 130 /* When there's no method print method names to result */
nexpaq 1:55a6170b404f 131 if (args.method_name == NULL) {
nexpaq 1:55a6170b404f 132 while (true) {
nexpaq 1:55a6170b404f 133 for (; cur_method->name != NULL; cur_method++) {
nexpaq 1:55a6170b404f 134 r.putData<const char*>(cur_method->name);
nexpaq 1:55a6170b404f 135 }
nexpaq 1:55a6170b404f 136
nexpaq 1:55a6170b404f 137 /* write_name_arr's args are references, so result and cur_method will have changed */
nexpaq 1:55a6170b404f 138 if (cur_method->super != 0) {
nexpaq 1:55a6170b404f 139 cur_method = cur_method->super(p);
nexpaq 1:55a6170b404f 140 } else {
nexpaq 1:55a6170b404f 141 return true;
nexpaq 1:55a6170b404f 142 }
nexpaq 1:55a6170b404f 143 }
nexpaq 1:55a6170b404f 144 }
nexpaq 1:55a6170b404f 145
nexpaq 1:55a6170b404f 146 /* Look through the methods for the one whose name matches */
nexpaq 1:55a6170b404f 147 while (true) {
nexpaq 1:55a6170b404f 148 for (; cur_method->name != NULL; cur_method++) {
nexpaq 1:55a6170b404f 149 if (strcmp(cur_method->name, args.method_name) == 0) {
nexpaq 1:55a6170b404f 150 (cur_method->method_caller)(p, &args, &r);
nexpaq 1:55a6170b404f 151 return true;
nexpaq 1:55a6170b404f 152 }
nexpaq 1:55a6170b404f 153 }
nexpaq 1:55a6170b404f 154
nexpaq 1:55a6170b404f 155 if (cur_method->super != 0) {
nexpaq 1:55a6170b404f 156 cur_method = cur_method->super(p);
nexpaq 1:55a6170b404f 157 } else {
nexpaq 1:55a6170b404f 158 /* end of methods and no match */
nexpaq 1:55a6170b404f 159 return false;
nexpaq 1:55a6170b404f 160 }
nexpaq 1:55a6170b404f 161
nexpaq 1:55a6170b404f 162 }
nexpaq 1:55a6170b404f 163 }
nexpaq 1:55a6170b404f 164
nexpaq 1:55a6170b404f 165 /* Then try a class */
nexpaq 1:55a6170b404f 166 for (const rpc_class *q = _classes; q != NULL; q = q->next) {
nexpaq 1:55a6170b404f 167 if (strcmp(q->name, args.obj_name) == 0) {
nexpaq 1:55a6170b404f 168 /* Matched the class name, so get its functions */
nexpaq 1:55a6170b404f 169 const rpc_function *cur_func = q->static_functions;
nexpaq 1:55a6170b404f 170 if (args.method_name == NULL) {
nexpaq 1:55a6170b404f 171 for (; cur_func->name != NULL; cur_func++) {
nexpaq 1:55a6170b404f 172 r.putData<const char*>(cur_func->name);
nexpaq 1:55a6170b404f 173 }
nexpaq 1:55a6170b404f 174 return true;
nexpaq 1:55a6170b404f 175 } else {
nexpaq 1:55a6170b404f 176 /* Otherwise call the appropriate function */
nexpaq 1:55a6170b404f 177 for (; cur_func->name != NULL; cur_func++) {
nexpaq 1:55a6170b404f 178 if (strcmp(cur_func->name, args.method_name) == 0) {
nexpaq 1:55a6170b404f 179 (cur_func->function_caller)(&args, &r);
nexpaq 1:55a6170b404f 180 return true;
nexpaq 1:55a6170b404f 181 }
nexpaq 1:55a6170b404f 182 }
nexpaq 1:55a6170b404f 183 return false;
nexpaq 1:55a6170b404f 184 }
nexpaq 1:55a6170b404f 185 }
nexpaq 1:55a6170b404f 186 }
nexpaq 1:55a6170b404f 187
nexpaq 1:55a6170b404f 188 return false;
nexpaq 1:55a6170b404f 189 }
nexpaq 1:55a6170b404f 190
nexpaq 1:55a6170b404f 191 } // namespace mbed