HTTP RPC Server mit vordefinierten Objekten

Dependencies:   EthernetInterface HttpServer Servo mbed-rtos mbed

Fork of RPCHTTPServerVariable by th.iotkit2.ch

Mittels RPCVariable lassen sich lokale Variablen setzen. Diese Variablen können gesetzt write oder gelesen read werden.

Mittels Ticker u.ä. Varianten lassen sich damit auch Objektwerte setzen, welche von RPC nicht unterstützt werden, z.B. Servo's.

Client

Wert setzen: http://<IP-Adresse mbed>/rpc/servo2/write+0.5

Committer:
stefan1691
Date:
Sun Mar 20 07:39:09 2016 +0000
Revision:
17:752e17b9aab4
Parent:
14:3835863bc412
https statt http verhindert Fehler

Who changed what in which revision?

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