Remote Procedure Call (RPC) over Websockets (uses MbedJSONValue)
Dependents: RPC_mbed_client RPC_Wifly_HelloWorld RPC_Ethernet_HelloWorld
MbedJSONRpc.cpp
00001 #include "MbedJSONRpc.h" 00002 00003 RPC_TYPE MbedJSONRpc::call(char * fn, char * dest, MbedJSONValue& val, MbedJSONValue& resp) { 00004 00005 char json[150]; 00006 RPC_TYPE t; 00007 string str = val.serialize(); 00008 int id = rand() % 100; 00009 MbedJSONValue tmp; 00010 00011 00012 sprintf(json, (const char *)MSG_CALL, my_id, dest, id, fn, str.c_str()); 00013 webs->send(json); 00014 t = waitAnswer(tmp, id, json); 00015 if (t != CALL_OK) 00016 return t; 00017 resp = tmp["res"]; 00018 return CALL_OK; 00019 } 00020 00021 RPC_TYPE MbedJSONRpc::waitAnswer(MbedJSONValue& v, int id, char * json) { 00022 Timer tmr; 00023 00024 tmr.start(); 00025 while (1) { 00026 if (tmr.read() > 5.0) { 00027 #ifdef DEBUG 00028 printf("timeout\r\n"); 00029 #endif 00030 return SERVER_NOT_CONNECTED; 00031 } 00032 if (webs->read(json)) { 00033 #ifdef DEBUG 00034 printf("receive: %s\r\n", json); 00035 #endif 00036 parse(v, json); 00037 return decodeMsg(v, id); 00038 } 00039 } 00040 } 00041 00042 int MbedJSONRpc::methodAlreadyRegistered(char * s) { 00043 for (int i = 0; i < index; i++) 00044 if (!strcmp(name[i], s)) 00045 return i; 00046 return -1; 00047 } 00048 00049 00050 int MbedJSONRpc::procAlreadyRegistered(char * s) { 00051 for (int i = 0; i < index_proc; i++) 00052 if (!strcmp(name_proc[i], s)) 00053 return i; 00054 return -1; 00055 } 00056 00057 void MbedJSONRpc::checkMethods(char * dest) { 00058 char json[150]; 00059 char name[5]; 00060 MbedJSONValue tmp; 00061 int id = rand() % 100; 00062 00063 sprintf(json, (const char *)MSG_INFO_METHODS, my_id, dest, id); 00064 webs->send(json); 00065 waitAnswer(tmp, id, json); 00066 printf("methods available on %s: ", dest); 00067 for (int i = 0; i < tmp.size() - 1; i++) { 00068 sprintf(name, "fn%d", i); 00069 printf("%s%c ", tmp[name].get<string>().c_str(), (i == tmp.size() - 2) ? ' ' : ','); 00070 } 00071 printf("\r\n"); 00072 } 00073 00074 RPC_TYPE MbedJSONRpc::decodeMsg(MbedJSONValue& v, int id) { 00075 00076 if (v.hasMember("id_msg")) 00077 if (v["id_msg"].get<int>() != -1 && id != v["id_msg"].get<int>()) { 00078 #ifdef DEBUG 00079 printf("bad id: %d\r\n",v["id_msg"].get<int>() ); 00080 #endif 00081 return ERR_ID; 00082 } 00083 00084 if (v.hasMember("msg")) { 00085 std::string s = v["msg"].get<std::string>(); 00086 if (!strcmp(s.c_str(), "RESULT")) { 00087 return CALL_OK; 00088 } 00089 if (!strcmp(s.c_str(), "REGISTER_OK")) { 00090 return REGISTER_OK; 00091 } 00092 } 00093 00094 //there is an error 00095 if (v.hasMember("cause")) { 00096 std::string s = v["cause"].get<std::string>(); 00097 if (!strcmp(s.c_str(), "JSON_PARSE_ERROR")) 00098 return JSON_PARSE_ERROR; 00099 if (!strcmp(s.c_str(), "JSON_RPC_ERROR")) 00100 return RPC_PARSE_ERROR; 00101 else if (!strcmp(s.c_str(), "METHOD_NOT_FOUND")) 00102 return PROC_NOT_FOUND; 00103 else if (!strcmp(s.c_str(), "CLIENT_NOT_CONNECTED")) 00104 return CLIENT_NOT_CONNECTED; 00105 } 00106 return RPC_PARSE_ERROR; 00107 00108 } 00109 00110 00111 RPC_TYPE MbedJSONRpc::registerMethod(const char * public_name, void (*fn)(MbedJSONValue& val, MbedJSONValue& res) ) { 00112 char json[100]; 00113 int id = rand() % 100; 00114 MbedJSONValue tmp; 00115 RPC_TYPE t; 00116 00117 sprintf(json, (const char *)MSG_REGISTER, my_id, id, public_name); 00118 webs->send(json); 00119 t = waitAnswer(tmp, id, json); 00120 if (t != REGISTER_OK) 00121 return t; 00122 if( index_proc == NB_METH ) 00123 index_proc = NB_METH - 1; 00124 proc[index_proc] = fn; 00125 name_proc[index_proc++] = public_name; 00126 return REGISTER_OK; 00127 } 00128 00129 00130 void MbedJSONRpc::work() { 00131 char json_recv[150]; 00132 DigitalOut led4(LED4); 00133 MbedJSONValue v, r; 00134 int i = -1; 00135 while (1) { 00136 wait(0.2); 00137 if (webs->read(json_recv)) { 00138 parse(v, json_recv); 00139 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")) { 00140 00141 string s = v["method"].get<std::string>(); 00142 00143 if ((i = methodAlreadyRegistered((char *)s.c_str())) != -1) { 00144 00145 obj[i]->execute(v["params"], r); 00146 sprintf(json_recv, (const char *)MSG_RESULT, my_id, 00147 v["from"].get<std::string>().c_str(), v["id_msg"].get<int>(), r.serialize().c_str()); 00148 webs->send(json_recv); 00149 00150 } else if ((i = procAlreadyRegistered((char *)s.c_str())) != -1) { 00151 00152 proc[i](v["params"], r); 00153 sprintf(json_recv, (const char *)MSG_RESULT, my_id, 00154 v["from"].get<std::string>().c_str(), v["id_msg"].get<int>(), r.serialize().c_str()); 00155 webs->send(json_recv); 00156 00157 } 00158 } 00159 00160 } 00161 //show that we are alive 00162 led4 = !led4; 00163 } 00164 }
Generated on Wed Jul 20 2022 02:14:25 by
