Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
rpc.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "rpc.h" 00017 00018 using namespace std; 00019 00020 namespace mbed { 00021 00022 RPC::RPC(const char *name) { 00023 _from_construct = false; 00024 if (name != NULL) { 00025 _name = new char[strlen(name) + 1]; 00026 strcpy(_name, name); 00027 } else { 00028 _name = new char[12]; 00029 sprintf(_name, "obj%p", this); 00030 } 00031 // put this object at head of the list 00032 _next = _head; 00033 _head = this; 00034 } 00035 00036 RPC::~RPC() { 00037 // remove this object from the list 00038 if (_head == this) { // first in the list, so just drop me 00039 _head = _next; 00040 } else { // find the object before me, then drop me 00041 RPC* p = _head; 00042 while (p->_next != this) { 00043 p = p->_next; 00044 } 00045 p->_next = _next; 00046 } 00047 } 00048 00049 const rpc_method *RPC::get_rpc_methods() { 00050 static const rpc_method methods[] = { 00051 {"delete", rpc_method_caller<RPC, &RPC::delete_self> }, 00052 RPC_METHOD_END 00053 }; 00054 return methods; 00055 } 00056 00057 RPC *RPC::lookup(const char *name) { 00058 size_t len = strlen(name); 00059 for (RPC *p = _head; p != NULL; p = p->_next) { 00060 /* Check that p->_name matches name and is the correct length */ 00061 if (strncmp(p->_name, name, len) == 0 && (strlen(p->_name) == len)) { 00062 return p; 00063 } 00064 } 00065 return NULL; 00066 } 00067 00068 void RPC::delete_self() { 00069 delete[] _name; 00070 if (_from_construct) { 00071 delete this; 00072 } 00073 } 00074 00075 void RPC::list_objs(Arguments *args, Reply *result) { 00076 for (RPC *ptr = RPC::_head; ptr != NULL; ptr = ptr->_next) { 00077 if (ptr->_from_construct) { 00078 result->putData<const char*>(ptr->_name); 00079 } 00080 } 00081 } 00082 00083 void RPC::clear(Arguments*, Reply*) { 00084 RPC *ptr = RPC::_head; 00085 while (ptr != NULL) { 00086 RPC *tmp = ptr; 00087 ptr = ptr->_next; 00088 delete[] tmp->_name; 00089 if (tmp->_from_construct) { 00090 delete tmp; 00091 } 00092 } 00093 } 00094 00095 const rpc_function RPC::_RPC_funcs[] = { 00096 {"clear", &RPC::clear }, 00097 { "objects", &RPC::list_objs }, 00098 RPC_METHOD_END 00099 }; 00100 00101 rpc_class RPC::_RPC_class = { "RPC", _RPC_funcs, NULL }; 00102 00103 RPC *RPC::_head = NULL; 00104 00105 rpc_class *RPC::_classes = &_RPC_class; 00106 00107 bool RPC::call(const char *request, char *reply) { 00108 if (request == NULL) return false; 00109 00110 Arguments args(request); 00111 Reply r(reply); 00112 00113 /* If there's no name print object and class names to result */ 00114 if (args.obj_name == NULL) { 00115 for (RPC *p = RPC::_head; p != NULL; p = p->_next) { 00116 r.putData<const char*>(p->_name); 00117 } 00118 for (rpc_class *c = RPC::_classes; c != NULL; c = c->next) { 00119 r.putData<const char*>(c->name); 00120 } 00121 return true; 00122 } 00123 00124 /* First try matching an instance */ 00125 RPC *p = lookup(args.obj_name); 00126 if (p != NULL) { 00127 /* Get the list of methods we support */ 00128 const rpc_method *cur_method = p->get_rpc_methods(); 00129 00130 /* When there's no method print method names to result */ 00131 if (args.method_name == NULL) { 00132 while (true) { 00133 for (; cur_method->name != NULL; cur_method++) { 00134 r.putData<const char*>(cur_method->name); 00135 } 00136 00137 /* write_name_arr's args are references, so result and cur_method will have changed */ 00138 if (cur_method->super != 0) { 00139 cur_method = cur_method->super(p); 00140 } else { 00141 return true; 00142 } 00143 } 00144 } 00145 00146 /* Look through the methods for the one whose name matches */ 00147 while (true) { 00148 for (; cur_method->name != NULL; cur_method++) { 00149 if (strcmp(cur_method->name, args.method_name) == 0) { 00150 (cur_method->method_caller)(p, &args, &r); 00151 return true; 00152 } 00153 } 00154 00155 if (cur_method->super != 0) { 00156 cur_method = cur_method->super(p); 00157 } else { 00158 /* end of methods and no match */ 00159 return false; 00160 } 00161 00162 } 00163 } 00164 00165 /* Then try a class */ 00166 for (const rpc_class *q = _classes; q != NULL; q = q->next) { 00167 if (strcmp(q->name, args.obj_name) == 0) { 00168 /* Matched the class name, so get its functions */ 00169 const rpc_function *cur_func = q->static_functions; 00170 if (args.method_name == NULL) { 00171 for (; cur_func->name != NULL; cur_func++) { 00172 r.putData<const char*>(cur_func->name); 00173 } 00174 return true; 00175 } else { 00176 /* Otherwise call the appropriate function */ 00177 for (; cur_func->name != NULL; cur_func++) { 00178 if (strcmp(cur_func->name, args.method_name) == 0) { 00179 (cur_func->function_caller)(&args, &r); 00180 return true; 00181 } 00182 } 00183 return false; 00184 } 00185 } 00186 } 00187 00188 return false; 00189 } 00190 00191 } // namespace mbed
Generated on Tue Jul 12 2022 13:31:22 by
