Remote Procedure Call (RPC) over Websockets (uses MbedJSONValue)

Dependents:   RPC_mbed_client RPC_Wifly_HelloWorld RPC_Ethernet_HelloWorld

Committer:
samux
Date:
Thu Sep 22 10:14:52 2011 +0000
Revision:
0:a53d1c86196c
Child:
2:af408b5cae75

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux 0:a53d1c86196c 1 #include "MbedJSONRpc.h"
samux 0:a53d1c86196c 2
samux 0:a53d1c86196c 3 RPC_TYPE MbedJSONRpc::call(char * fn, char * dest, MbedRpcValue& val, MbedRpcValue& 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 0:a53d1c86196c 9 MbedRpcValue 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 0:a53d1c86196c 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 0:a53d1c86196c 21 RPC_TYPE MbedJSONRpc::waitAnswer(MbedRpcValue& 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 0:a53d1c86196c 60 MbedRpcValue 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 0:a53d1c86196c 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 0:a53d1c86196c 74 RPC_TYPE MbedJSONRpc::decodeMsg(MbedRpcValue& 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 0:a53d1c86196c 111 RPC_TYPE MbedJSONRpc::registerMethod(const char * public_name, void (*fn)(MbedRpcValue& val, MbedRpcValue& res) ) {
samux 0:a53d1c86196c 112 char json[100];
samux 0:a53d1c86196c 113 int id = rand() % 100;
samux 0:a53d1c86196c 114 MbedRpcValue 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 0:a53d1c86196c 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 0:a53d1c86196c 133 MbedRpcValue 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 0:a53d1c86196c 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 0:a53d1c86196c 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 }