Remote Procedure Call (RPC) over Websockets (uses MbedJSONValue)
Dependents: RPC_mbed_client RPC_Wifly_HelloWorld RPC_Ethernet_HelloWorld
MbedJSONRpc.cpp@7:067cb01b491e, 2012-08-23 (annotated)
- Committer:
- samux
- Date:
- Thu Aug 23 14:23:37 2012 +0000
- Revision:
- 7:067cb01b491e
- Parent:
- 2:af408b5cae75
update with new websocket client
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
samux | 0:a53d1c86196c | 1 | #include "MbedJSONRpc.h" |
samux | 0:a53d1c86196c | 2 | |
samux | 2:af408b5cae75 | 3 | RPC_TYPE MbedJSONRpc::call(char * fn, char * dest, MbedJSONValue& val, MbedJSONValue& resp) { |
samux | 0:a53d1c86196c | 4 | |
samux | 0:a53d1c86196c | 5 | char json[150]; |
samux | 0:a53d1c86196c | 6 | RPC_TYPE t; |
samux | 0:a53d1c86196c | 7 | string str = val.serialize(); |
samux | 0:a53d1c86196c | 8 | int id = rand() % 100; |
samux | 2:af408b5cae75 | 9 | MbedJSONValue tmp; |
samux | 0:a53d1c86196c | 10 | |
samux | 0:a53d1c86196c | 11 | |
samux | 0:a53d1c86196c | 12 | sprintf(json, (const char *)MSG_CALL, my_id, dest, id, fn, str.c_str()); |
samux | 7:067cb01b491e | 13 | webs->send(json); |
samux | 0:a53d1c86196c | 14 | t = waitAnswer(tmp, id, json); |
samux | 0:a53d1c86196c | 15 | if (t != CALL_OK) |
samux | 0:a53d1c86196c | 16 | return t; |
samux | 0:a53d1c86196c | 17 | resp = tmp["res"]; |
samux | 0:a53d1c86196c | 18 | return CALL_OK; |
samux | 0:a53d1c86196c | 19 | } |
samux | 0:a53d1c86196c | 20 | |
samux | 2:af408b5cae75 | 21 | RPC_TYPE MbedJSONRpc::waitAnswer(MbedJSONValue& v, int id, char * json) { |
samux | 0:a53d1c86196c | 22 | Timer tmr; |
samux | 0:a53d1c86196c | 23 | |
samux | 0:a53d1c86196c | 24 | tmr.start(); |
samux | 0:a53d1c86196c | 25 | while (1) { |
samux | 0:a53d1c86196c | 26 | if (tmr.read() > 5.0) { |
samux | 0:a53d1c86196c | 27 | #ifdef DEBUG |
samux | 0:a53d1c86196c | 28 | printf("timeout\r\n"); |
samux | 0:a53d1c86196c | 29 | #endif |
samux | 0:a53d1c86196c | 30 | return SERVER_NOT_CONNECTED; |
samux | 0:a53d1c86196c | 31 | } |
samux | 0:a53d1c86196c | 32 | if (webs->read(json)) { |
samux | 0:a53d1c86196c | 33 | #ifdef DEBUG |
samux | 0:a53d1c86196c | 34 | printf("receive: %s\r\n", json); |
samux | 0:a53d1c86196c | 35 | #endif |
samux | 0:a53d1c86196c | 36 | parse(v, json); |
samux | 0:a53d1c86196c | 37 | return decodeMsg(v, id); |
samux | 0:a53d1c86196c | 38 | } |
samux | 0:a53d1c86196c | 39 | } |
samux | 0:a53d1c86196c | 40 | } |
samux | 0:a53d1c86196c | 41 | |
samux | 0:a53d1c86196c | 42 | int MbedJSONRpc::methodAlreadyRegistered(char * s) { |
samux | 0:a53d1c86196c | 43 | for (int i = 0; i < index; i++) |
samux | 0:a53d1c86196c | 44 | if (!strcmp(name[i], s)) |
samux | 0:a53d1c86196c | 45 | return i; |
samux | 0:a53d1c86196c | 46 | return -1; |
samux | 0:a53d1c86196c | 47 | } |
samux | 0:a53d1c86196c | 48 | |
samux | 0:a53d1c86196c | 49 | |
samux | 0:a53d1c86196c | 50 | int MbedJSONRpc::procAlreadyRegistered(char * s) { |
samux | 0:a53d1c86196c | 51 | for (int i = 0; i < index_proc; i++) |
samux | 0:a53d1c86196c | 52 | if (!strcmp(name_proc[i], s)) |
samux | 0:a53d1c86196c | 53 | return i; |
samux | 0:a53d1c86196c | 54 | return -1; |
samux | 0:a53d1c86196c | 55 | } |
samux | 0:a53d1c86196c | 56 | |
samux | 0:a53d1c86196c | 57 | void MbedJSONRpc::checkMethods(char * dest) { |
samux | 0:a53d1c86196c | 58 | char json[150]; |
samux | 0:a53d1c86196c | 59 | char name[5]; |
samux | 2:af408b5cae75 | 60 | MbedJSONValue tmp; |
samux | 0:a53d1c86196c | 61 | int id = rand() % 100; |
samux | 0:a53d1c86196c | 62 | |
samux | 0:a53d1c86196c | 63 | sprintf(json, (const char *)MSG_INFO_METHODS, my_id, dest, id); |
samux | 7:067cb01b491e | 64 | webs->send(json); |
samux | 0:a53d1c86196c | 65 | waitAnswer(tmp, id, json); |
samux | 0:a53d1c86196c | 66 | printf("methods available on %s: ", dest); |
samux | 0:a53d1c86196c | 67 | for (int i = 0; i < tmp.size() - 1; i++) { |
samux | 0:a53d1c86196c | 68 | sprintf(name, "fn%d", i); |
samux | 0:a53d1c86196c | 69 | printf("%s%c ", tmp[name].get<string>().c_str(), (i == tmp.size() - 2) ? ' ' : ','); |
samux | 0:a53d1c86196c | 70 | } |
samux | 0:a53d1c86196c | 71 | printf("\r\n"); |
samux | 0:a53d1c86196c | 72 | } |
samux | 0:a53d1c86196c | 73 | |
samux | 2:af408b5cae75 | 74 | RPC_TYPE MbedJSONRpc::decodeMsg(MbedJSONValue& v, int id) { |
samux | 0:a53d1c86196c | 75 | |
samux | 0:a53d1c86196c | 76 | if (v.hasMember("id_msg")) |
samux | 0:a53d1c86196c | 77 | if (v["id_msg"].get<int>() != -1 && id != v["id_msg"].get<int>()) { |
samux | 0:a53d1c86196c | 78 | #ifdef DEBUG |
samux | 0:a53d1c86196c | 79 | printf("bad id: %d\r\n",v["id_msg"].get<int>() ); |
samux | 0:a53d1c86196c | 80 | #endif |
samux | 0:a53d1c86196c | 81 | return ERR_ID; |
samux | 0:a53d1c86196c | 82 | } |
samux | 0:a53d1c86196c | 83 | |
samux | 0:a53d1c86196c | 84 | if (v.hasMember("msg")) { |
samux | 0:a53d1c86196c | 85 | std::string s = v["msg"].get<std::string>(); |
samux | 0:a53d1c86196c | 86 | if (!strcmp(s.c_str(), "RESULT")) { |
samux | 0:a53d1c86196c | 87 | return CALL_OK; |
samux | 0:a53d1c86196c | 88 | } |
samux | 0:a53d1c86196c | 89 | if (!strcmp(s.c_str(), "REGISTER_OK")) { |
samux | 0:a53d1c86196c | 90 | return REGISTER_OK; |
samux | 0:a53d1c86196c | 91 | } |
samux | 0:a53d1c86196c | 92 | } |
samux | 0:a53d1c86196c | 93 | |
samux | 0:a53d1c86196c | 94 | //there is an error |
samux | 0:a53d1c86196c | 95 | if (v.hasMember("cause")) { |
samux | 0:a53d1c86196c | 96 | std::string s = v["cause"].get<std::string>(); |
samux | 0:a53d1c86196c | 97 | if (!strcmp(s.c_str(), "JSON_PARSE_ERROR")) |
samux | 0:a53d1c86196c | 98 | return JSON_PARSE_ERROR; |
samux | 0:a53d1c86196c | 99 | if (!strcmp(s.c_str(), "JSON_RPC_ERROR")) |
samux | 0:a53d1c86196c | 100 | return RPC_PARSE_ERROR; |
samux | 0:a53d1c86196c | 101 | else if (!strcmp(s.c_str(), "METHOD_NOT_FOUND")) |
samux | 0:a53d1c86196c | 102 | return PROC_NOT_FOUND; |
samux | 0:a53d1c86196c | 103 | else if (!strcmp(s.c_str(), "CLIENT_NOT_CONNECTED")) |
samux | 0:a53d1c86196c | 104 | return CLIENT_NOT_CONNECTED; |
samux | 0:a53d1c86196c | 105 | } |
samux | 0:a53d1c86196c | 106 | return RPC_PARSE_ERROR; |
samux | 0:a53d1c86196c | 107 | |
samux | 0:a53d1c86196c | 108 | } |
samux | 0:a53d1c86196c | 109 | |
samux | 0:a53d1c86196c | 110 | |
samux | 2:af408b5cae75 | 111 | RPC_TYPE MbedJSONRpc::registerMethod(const char * public_name, void (*fn)(MbedJSONValue& val, MbedJSONValue& res) ) { |
samux | 0:a53d1c86196c | 112 | char json[100]; |
samux | 0:a53d1c86196c | 113 | int id = rand() % 100; |
samux | 2:af408b5cae75 | 114 | MbedJSONValue tmp; |
samux | 0:a53d1c86196c | 115 | RPC_TYPE t; |
samux | 0:a53d1c86196c | 116 | |
samux | 0:a53d1c86196c | 117 | sprintf(json, (const char *)MSG_REGISTER, my_id, id, public_name); |
samux | 7:067cb01b491e | 118 | webs->send(json); |
samux | 0:a53d1c86196c | 119 | t = waitAnswer(tmp, id, json); |
samux | 0:a53d1c86196c | 120 | if (t != REGISTER_OK) |
samux | 0:a53d1c86196c | 121 | return t; |
samux | 0:a53d1c86196c | 122 | if( index_proc == NB_METH ) |
samux | 0:a53d1c86196c | 123 | index_proc = NB_METH - 1; |
samux | 0:a53d1c86196c | 124 | proc[index_proc] = fn; |
samux | 0:a53d1c86196c | 125 | name_proc[index_proc++] = public_name; |
samux | 0:a53d1c86196c | 126 | return REGISTER_OK; |
samux | 0:a53d1c86196c | 127 | } |
samux | 0:a53d1c86196c | 128 | |
samux | 0:a53d1c86196c | 129 | |
samux | 0:a53d1c86196c | 130 | void MbedJSONRpc::work() { |
samux | 0:a53d1c86196c | 131 | char json_recv[150]; |
samux | 0:a53d1c86196c | 132 | DigitalOut led4(LED4); |
samux | 2:af408b5cae75 | 133 | MbedJSONValue v, r; |
samux | 0:a53d1c86196c | 134 | int i = -1; |
samux | 0:a53d1c86196c | 135 | while (1) { |
samux | 0:a53d1c86196c | 136 | wait(0.2); |
samux | 0:a53d1c86196c | 137 | if (webs->read(json_recv)) { |
samux | 0:a53d1c86196c | 138 | parse(v, json_recv); |
samux | 0:a53d1c86196c | 139 | if (v.hasMember("method") && v.hasMember("from") && v.hasMember("id_msg") && v.hasMember("params") && v.hasMember("msg") && !strcmp(v["msg"].get<std::string>().c_str(), "CALL")) { |
samux | 0:a53d1c86196c | 140 | |
samux | 0:a53d1c86196c | 141 | string s = v["method"].get<std::string>(); |
samux | 0:a53d1c86196c | 142 | |
samux | 0:a53d1c86196c | 143 | if ((i = methodAlreadyRegistered((char *)s.c_str())) != -1) { |
samux | 0:a53d1c86196c | 144 | |
samux | 0:a53d1c86196c | 145 | obj[i]->execute(v["params"], r); |
samux | 0:a53d1c86196c | 146 | sprintf(json_recv, (const char *)MSG_RESULT, my_id, |
samux | 0:a53d1c86196c | 147 | v["from"].get<std::string>().c_str(), v["id_msg"].get<int>(), r.serialize().c_str()); |
samux | 7:067cb01b491e | 148 | webs->send(json_recv); |
samux | 0:a53d1c86196c | 149 | |
samux | 0:a53d1c86196c | 150 | } else if ((i = procAlreadyRegistered((char *)s.c_str())) != -1) { |
samux | 0:a53d1c86196c | 151 | |
samux | 0:a53d1c86196c | 152 | proc[i](v["params"], r); |
samux | 0:a53d1c86196c | 153 | sprintf(json_recv, (const char *)MSG_RESULT, my_id, |
samux | 0:a53d1c86196c | 154 | v["from"].get<std::string>().c_str(), v["id_msg"].get<int>(), r.serialize().c_str()); |
samux | 7:067cb01b491e | 155 | webs->send(json_recv); |
samux | 0:a53d1c86196c | 156 | |
samux | 0:a53d1c86196c | 157 | } |
samux | 0:a53d1c86196c | 158 | } |
samux | 0:a53d1c86196c | 159 | |
samux | 0:a53d1c86196c | 160 | } |
samux | 0:a53d1c86196c | 161 | //show that we are alive |
samux | 0:a53d1c86196c | 162 | led4 = !led4; |
samux | 0:a53d1c86196c | 163 | } |
samux | 0:a53d1c86196c | 164 | } |