This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Fork of libMiMic by
Revision 72:c118a7aa37a3, committed 2014-06-13
- Comitter:
- nyatla
- Date:
- Fri Jun 13 11:06:33 2014 +0000
- Parent:
- 71:855020258513
- Child:
- 73:8c7dd6fd462e
- Commit message:
- mbedAPI???????
Changed in this revision
--- a/core/http/json/NyLPC_cJsonRpcParser.h Tue Jun 10 03:30:41 2014 +0000 +++ b/core/http/json/NyLPC_cJsonRpcParser.h Fri Jun 13 11:06:33 2014 +0000 @@ -6,6 +6,15 @@ #include "NyLPC_stdlib.h" + +#define NyLPC_TJsonRpcErrorCode_PARSE_ERROR (-32700) +#define NyLPC_TJsonRpcErrorCode_INVALID_REQUEST (-32600) +#define NyLPC_TJsonRpcErrorCode_METHOD_NOT_FOUND (-32601) +#define NyLPC_TJsonRpcErrorCode_INVALID_PARAMS (-32602) +#define NyLPC_TJsonRpcErrorCode_INTERNAL_ERROR (-32603) +#define NyLPC_TJsonRpcErrorCode_SERVER_ERROR_BASE (-32000) + + /** 型定義*/ union NyLPC_TJsonRpcParserResult; @@ -248,4 +257,3 @@ #endif /* __cplusplus */ #endif /* NYLPC_CJSONRPCPARSER4_H_ */ -
--- a/core/include/NyLPC_stdlib.h Tue Jun 10 03:30:41 2014 +0000 +++ b/core/include/NyLPC_stdlib.h Fri Jun 13 11:06:33 2014 +0000 @@ -538,7 +538,14 @@ */ int NyLPC_ctox(char i); - +/** + * va_copyがない場合の対処だお + */ +#ifndef va_copy +# define NyLPC_va_copy(dest, src) ((dest) = (src)) +#else +# define NyLPC_va_copy(dest, src) va_copy((dest),(src)) +#endif #ifdef __cplusplus }
--- a/core/net/httpd/mod/NyLPC_cModJsonRpc.c Tue Jun 10 03:30:41 2014 +0000 +++ b/core/net/httpd/mod/NyLPC_cModJsonRpc.c Fri Jun 13 11:06:33 2014 +0000 @@ -85,28 +85,71 @@ * ここで指定した書式文字列は、"そのまま"パラメータ部に表示されます。文字列を返す場合は、次のように\"でエスケープしてください。 * '0,1,2,-1,\"result\",3' */ -NyLPC_TBool NyLPC_cModJsonRpc_putResult(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,NyLPC_TInt32 i_result,const NyLPC_TChar* i_params_fmt,...) +NyLPC_TBool NyLPC_cModJsonRpc_putResult(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,const NyLPC_TChar* i_params_fmt,...) +{ + NyLPC_TBool r; + va_list a; + //書き込み文字数の事前計算 + va_start(a,i_params_fmt); + r=NyLPC_cModJsonRpc_putResultV(i_inst,i_id,i_params_fmt,a); + va_end(a); + return r; +} + +/** + * @param i_params_fmt + * パラメータ部のフォーマット文字列です。NyLPC_cFormatWriterと同等の構文を使用できます。 + * ここで指定した書式文字列は、"そのまま"パラメータ部に表示されます。文字列を返す場合は、次のように\"でエスケープしてください。 + * '0,1,2,-1,\"result\",3' + */ +NyLPC_TBool NyLPC_cModJsonRpc_putResultV(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,const NyLPC_TChar* i_params_fmt,va_list i_a) { NyLPC_TBool r; va_list a; NyLPC_TInt16 l; //書き込み文字数の事前計算 - va_start(a,i_params_fmt); - l=NyLPC_cModWebSocket_testFormat(&i_inst->super,"{\"result\":%d,\"params\":[",i_result); + NyLPC_va_copy(a,i_a); + l=NyLPC_cModWebSocket_testFormat(&i_inst->super,"{\"jsonrpc\":\"2.0\",\"result\":["); l+=NyLPC_cModWebSocket_testFormatV(&i_inst->super,i_params_fmt,a); l+=NyLPC_cModWebSocket_testFormat(&i_inst->super,"],\"id\":%d}",i_id); va_end(a); //バルク書き込み - va_start(a,i_params_fmt); NyLPC_cModWebSocket_startBulkWrite(&i_inst->super,l); - r=NyLPC_cModWebSocket_writeBulkFormat(&i_inst->super,"{\"result\":%d,\"params\":[",i_result); - r=r&&NyLPC_cModWebSocket_writeBulkFormatV(&i_inst->super,i_params_fmt,a); + r=NyLPC_cModWebSocket_writeBulkFormat(&i_inst->super,"{\"jsonrpc\":\"2.0\",\"result\":["); + r=r&&NyLPC_cModWebSocket_writeBulkFormatV(&i_inst->super,i_params_fmt,i_a); r=r&&NyLPC_cModWebSocket_writeBulkFormat(&i_inst->super,"],\"id\":%d}",i_id); r=r&&NyLPC_cModWebSocket_endBulkWrite(&i_inst->super); - va_end(a); return r; } +struct CodeMsgTbl{ + const char* n; + NyLPC_TInt32 id; +}; +const static struct CodeMsgTbl _table[]= +{ + {"Parse error",NyLPC_TJsonRpcErrorCode_PARSE_ERROR}, + {"Invalid Request",NyLPC_TJsonRpcErrorCode_INVALID_REQUEST}, + {"Method not found",NyLPC_TJsonRpcErrorCode_METHOD_NOT_FOUND}, + {"Invalid params",NyLPC_TJsonRpcErrorCode_INVALID_PARAMS}, + {"Internal error",NyLPC_TJsonRpcErrorCode_INTERNAL_ERROR}, + {"Server error",NyLPC_TJsonRpcErrorCode_SERVER_ERROR_BASE} +}; +static const NyLPC_TChar* code2msg(NyLPC_TInt32 i_id) +{ + int i; + for(i=0;i<6;i++){ + if(i_id==_table[i].id){ + return _table[i].n; + } + } + return _table[6].n; +} + +NyLPC_TBool NyLPC_cModJsonRpc_putError(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,NyLPC_TInt32 i_code) +{ + return NyLPC_cModWebSocket_writeFormat(&i_inst->super,"{\"jsonrpc\":\"2.0\",\"error\":{\"code\": %d, \"message\": \"%s\"},\"id\":%d}",i_code,code2msg(i_code),i_id); +}
--- a/core/net/httpd/mod/NyLPC_cModJsonRpc.h Tue Jun 10 03:30:41 2014 +0000 +++ b/core/net/httpd/mod/NyLPC_cModJsonRpc.h Fri Jun 13 11:06:33 2014 +0000 @@ -74,11 +74,12 @@ */ const union NyLPC_TJsonRpcParserResult* NyLPC_cModJsonRpc_getMessage(NyLPC_TcModJsonRpc_t* i_inst); -NyLPC_TBool NyLPC_cModJsonRpc_putResult(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,NyLPC_TInt32 i_result,const NyLPC_TChar* i_params_fmt,...); +NyLPC_TBool NyLPC_cModJsonRpc_putResult(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,const NyLPC_TChar* i_params_fmt,...); +NyLPC_TBool NyLPC_cModJsonRpc_putResultV(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,const NyLPC_TChar* i_params_fmt,va_list i_a); +NyLPC_TBool NyLPC_cModJsonRpc_putError(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,NyLPC_TInt32 i_code); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* NYLPC_CMODJSONRPC_H_ */ -
--- a/core/net/httpd/mod/NyLPC_cModWebSocket.c Tue Jun 10 03:30:41 2014 +0000 +++ b/core/net/httpd/mod/NyLPC_cModWebSocket.c Fri Jun 13 11:06:33 2014 +0000 @@ -658,9 +658,7 @@ return NyLPC_TBool_FALSE; } -#ifndef va_copy -# define va_copy(dest, src) ((dest) = (src)) -#endif + NyLPC_TBool NyLPC_cModWebSocket_writeFormatV(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,va_list args) { @@ -670,7 +668,7 @@ NyLPC_cModWebSocket_update(i_inst,0); //書式文字列の長さを計算 - va_copy(a,args); + NyLPC_va_copy(a,args); l=NyLPC_cFormatWriter_length(i_fmt,a); va_end(a); if(!NyLPC_cModWebSocket_writePayloadHeader(i_inst,l)){
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed/jsonrpc/MbedApi.h Fri Jun 13 11:06:33 2014 +0000 @@ -0,0 +1,4 @@ +namespace MiMic +{ + extern const struct NyLPC_TJsonRpcMethodDef RpcDigitalOut[]; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed/jsonrpc/RpcDigitalOut.cpp Fri Jun 13 11:06:33 2014 +0000 @@ -0,0 +1,108 @@ +#include "NyLPC_http.h" +#include "mod/ModJsonRpc.h" +#include "mbed.h" +namespace MiMic +{ + class RpcHandlerBase + { + public: + static void addNewObjectBatch(ModJsonRpc& i_mod,unsigned int i_id,void* i_new_object) + { + int i=i_mod.addObject(i_new_object); + if(i<0){ + delete i_new_object; + i_mod.putError(i_id,ModJsonRpc::INVALID_PARAMS); + return; + } + i_mod.putResult(i_id,"%d",i); + return; + } + static void* getObjectBatch(ModJsonRpc& i_mod,unsigned int i_id,int i_iid) + { + void* ret=i_mod.getObject(i_iid); + if(ret==NULL){ + i_mod.putError(i_id,ModJsonRpc::INTERNAL_ERROR); + } + return ret; + } + }; + + class DigitalOutHandler :RpcHandlerBase + { + public: + static NyLPC_TBool new1(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) + { + ModJsonRpc* mod=(ModJsonRpc*)i_param; + NyLPC_TUInt32 pin; + if(!NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,0,&pin)){ + mod->putError(i_rpc->method.id,ModJsonRpc::INVALID_PARAMS); + }else{ + addNewObjectBatch(*mod,i_rpc->method.id,new DigitalOut(PinName(pin))); + } + return NyLPC_TBool_TRUE; + } + static NyLPC_TBool new2(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) + { + ModJsonRpc* mod=(ModJsonRpc*)i_param; + NyLPC_TUInt32 pin; + NyLPC_TInt32 value; + //pin number + if( (!NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,0,&pin)) || + (!NyLPC_TJsonRpcParserResult_getInt32(i_rpc,1,&value))) + { + mod->putError(i_rpc->method.id,ModJsonRpc::INVALID_PARAMS); + }else{ + addNewObjectBatch(*mod,i_rpc->method.id,new DigitalOut(PinName(pin),value)); + } + return NyLPC_TBool_TRUE; + } + static NyLPC_TBool write(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) + { + ModJsonRpc* mod=(ModJsonRpc*)i_param; + NyLPC_TInt32 iid,value; + if( (!NyLPC_TJsonRpcParserResult_getInt32(i_rpc,0,&iid)) || + (!NyLPC_TJsonRpcParserResult_getInt32(i_rpc,1,&value))) + { + mod->putError(i_rpc->method.id,ModJsonRpc::INVALID_PARAMS); + }else{ + DigitalOut* inst=(DigitalOut*)getObjectBatch(*mod,i_rpc->method.id,iid); + if(inst!=NULL){ + inst->write(value); + mod->putResult(i_rpc->method.id,""); + } + } + return NyLPC_TBool_TRUE; + } + static NyLPC_TBool read(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) + { + ModJsonRpc* mod=(ModJsonRpc*)i_param; + NyLPC_TInt32 iid; + if( (!NyLPC_TJsonRpcParserResult_getInt32(i_rpc,0,&iid))) + { + mod->putError(i_rpc->method.id,ModJsonRpc::INVALID_PARAMS); + }else{ + DigitalOut* inst=(DigitalOut*)getObjectBatch(*mod,i_rpc->method.id,iid); + if(inst!=NULL){ + int v=inst->read(); + mod->putResult(i_rpc->method.id,"%d",v); + } + } + return NyLPC_TBool_TRUE; + } + }; + + + + const struct NyLPC_TJsonRpcMethodDef RpcDigitalOut[]= + { + { "_new1" ,"u" ,DigitalOutHandler::new1}, + { "_new2" ,"ud" ,DigitalOutHandler::new2}, + { "write" ,"dd" ,DigitalOutHandler::write}, + { "read" ,"d" ,DigitalOutHandler::read}, + { NULL ,NULL ,NULL} + }; + + + + +}
--- a/mbed/mimic.h Tue Jun 10 03:30:41 2014 +0000 +++ b/mbed/mimic.h Fri Jun 13 11:06:33 2014 +0000 @@ -21,6 +21,7 @@ #include "mod/ModFileIo.h" #include "mod/ModUPnPDevice.h" #include "mod/ModWebSocket.h" +#include "mod/ModJsonRpc.h" #include "LocalFileSystem2.h" using namespace MiMic; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed/mod/ModJsonRpc.cpp Fri Jun 13 11:06:33 2014 +0000 @@ -0,0 +1,118 @@ +#include "ModJsonRpc.h" +#include "../net/httpd/mod/NyLPC_cModWebSocket_protected.h" +#include "HttpdConnection.h" + +namespace MiMic +{ + #define NUM_OF_OBJECTS 32 + + ModJsonRpc::ModJsonRpc(const char* i_path,const struct NyLPC_TJsonRpcClassDef** i_rpc_table):ModBaseClass(i_path) + { + this->_mod=NULL; + this->_rpc_table=i_rpc_table; + } + ModJsonRpc::ModJsonRpc() + { + this->_mod=NULL; + } + ModJsonRpc::~ModJsonRpc() + { + if(this->_mod!=NULL){ + NyLPC_cModJsonRpc_finalize(this->_mod); + this->_mod=NULL; + } + } + void ModJsonRpc::setParam(const char* i_path,const struct NyLPC_TJsonRpcClassDef** i_rpc_table) + { + ModBaseClass::setParam(i_path); + this->_rpc_table=i_rpc_table; + } + bool ModJsonRpc::execute(HttpdConnection& i_connection) + { + if(this->_mod!=NULL){ + return false; + } + this->_mod=(NyLPC_TcModJsonRpc_t*)malloc(sizeof(NyLPC_TcModJsonRpc_t)); + if(this->_mod==NULL){ + return false; + } + bool ret=false; + //initialize table + this->_objects=new void*[NUM_OF_OBJECTS]; + memset(this->_objects,sizeof(void*)*NUM_OF_OBJECTS,0); + + //initialize websocket + NyLPC_cModJsonRpc_initialize(this->_mod,this->_path,this->_rpc_table); + if(NyLPC_cModJsonRpc_canHandle(this->_mod,i_connection._ref_inst)){ + ret=NyLPC_cModJsonRpc_execute(this->_mod,i_connection._ref_inst)?true:false; + } + NyLPC_cModJsonRpc_finalize(this->_mod); + free(this->_mod); + this->_mod=NULL; + + for(int i=0;i<NUM_OF_OBJECTS;i++){ + if(this->_objects[i]!=NULL){ + delete this->_objects[i]; + } + } + return ret; + } + + void ModJsonRpc::dispatchRpcCall() + { + const union NyLPC_TJsonRpcParserResult* rpc_result; + for(;;){ + if(!NyLPC_cModJsonRpc_processRpcMessage(this->_mod)){ + break; + } + //メッセージ取得を試行 + rpc_result=NyLPC_cModJsonRpc_getMessage(this->_mod); + if(rpc_result==NULL){ + //nothing + continue; + } + if(NyLPC_TJsonRpcParserResult_hasMethodHandler(rpc_result)){ + if(NyLPC_TJsonRpcParserResult_callMethodHandler(rpc_result,this)){ + continue; + }else{ + //function failed. + break; + } + }else{ + //no handler + break; + } + } + NyLPC_cModJsonRpc_close(this->_mod,1000); + return; + } + bool ModJsonRpc::putResult(unsigned int i_id,const char* i_params_fmt,...) + { + bool ret; + va_list a; + va_start(a,i_params_fmt); + ret=NyLPC_cModJsonRpc_putResultV(this->_mod,i_id,i_params_fmt,a)?true:false; + va_end(a); + return ret; + } + bool ModJsonRpc::putError(unsigned int i_id,int i_code) + { + return NyLPC_cModJsonRpc_putError(this->_mod,i_id,i_code)?true:false; + } + + int ModJsonRpc::addObject(void* i_object) + { + for(int i=0;i<NUM_OF_OBJECTS;i++){ + if(this->_objects[i]==NULL){ + this->_objects[i]=i_object; + return i; + } + } + return -1; + } + void* ModJsonRpc::getObject(int i_oid) + { + return this->_objects[i_oid]; + } + +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed/mod/ModJsonRpc.h Fri Jun 13 11:06:33 2014 +0000 @@ -0,0 +1,60 @@ +#include "NyLPC_net.h" +#include "ModBaseClass.h" +#include "HttpdConnection.h" +#include "Httpd.h" +#include "Net.h" +#include <vector> + +namespace MiMic +{ + class HttpdConnection; + + /** + * This class is Websocket module. + * The class provides 3 services. + * <ul> + * <li>d.xml - a device description.</li> + * <li>control/xx - soap handler</li> + * <li>event/xx -event handler.</li> + * </ul> + */ + class ModJsonRpc:ModBaseClass + { + private: + public: + const static int PARSE_ERROR=NyLPC_TJsonRpcErrorCode_PARSE_ERROR; + const static int INVALID_REQUEST=NyLPC_TJsonRpcErrorCode_INVALID_REQUEST; + const static int METHOD_NOT_FOUND=NyLPC_TJsonRpcErrorCode_METHOD_NOT_FOUND; + const static int INVALID_PARAMS=NyLPC_TJsonRpcErrorCode_INVALID_PARAMS; + const static int INTERNAL_ERROR=NyLPC_TJsonRpcErrorCode_INTERNAL_ERROR; + const static int SERVER_ERROR_BASE=NyLPC_TJsonRpcErrorCode_SERVER_ERROR_BASE; + private: + void** _objects; + const struct NyLPC_TJsonRpcClassDef** _rpc_table; + protected: + NyLPC_TcModJsonRpc_t* _mod; + public: + ModJsonRpc(); + /** + * @param i_rpc_table + * An address of Json RPC functions table. + */ + ModJsonRpc(const char* i_path,const struct NyLPC_TJsonRpcClassDef** i_rpc_table); + virtual ~ModJsonRpc(); + void setParam(const char* i_path,const struct NyLPC_TJsonRpcClassDef** i_rpc_table); + /** + * This function prepares Json rpc loop with websocket negotiation. + * @return + * true if successful;otherwishe false. + */ + bool execute(HttpdConnection& i_connection); + void dispatchRpcCall(); + + public: + //for development + int addObject(void* i_object); + void* getObject(int i_oid); + bool putResult(unsigned int i_id,const char* i_params_fmt,...); + bool putError(unsigned int i_id,int i_code); + }; +} \ No newline at end of file
--- a/mbed/mod/ModWebSocket.cpp Tue Jun 10 03:30:41 2014 +0000 +++ b/mbed/mod/ModWebSocket.cpp Fri Jun 13 11:06:33 2014 +0000 @@ -33,17 +33,16 @@ if(this->_mod==NULL){ return false; } + bool ret=false; //initialize websocket NyLPC_cModWebSocket_initialize(this->_mod,this->_path); if(NyLPC_cModWebSocket_canHandle(this->_mod,i_connection._ref_inst)){ - if(NyLPC_cModWebSocket_execute(this->_mod,i_connection._ref_inst)){ - return true; - } + ret=NyLPC_cModWebSocket_execute(this->_mod,i_connection._ref_inst)?true:false; } NyLPC_cModWebSocket_finalize(this->_mod); free(this->_mod); this->_mod=NULL; - return false; + return ret; } bool ModWebSocket::write(const void* i_tx_buf,int i_tx_size) { @@ -53,38 +52,17 @@ return NyLPC_cModWebSocket_write(this->_mod,i_tx_buf,i_tx_size)?true:false; } -static NyLPC_TBool fmt_handler(void* i_inst,const void* i_buf,NyLPC_TUInt32 i_len) -{ - return NyLPC_iHttpPtrStream_write((NyLPC_TiHttpPtrStream_t*)i_inst,i_buf,i_len); -} + - bool ModWebSocket::writeF(const char* i_fmt,...) + bool ModWebSocket::writeFormat(const char* i_fmt,...) { - NyLPC_TInt16 l; + bool ret; va_list a; //ストリームの状態を更新する。 - NyLPC_cModWebSocket_update(this->_mod,0); - - //書式文字列の長さを計算 va_start(a,i_fmt); - l=NyLPC_cFormatWriter_length(i_fmt,a); + ret=NyLPC_cModWebSocket_writeFormatV(this->_mod,i_fmt,a)?true:false; va_end(a); - if(!NyLPC_cModWebSocket_writePayloadHeader(this->_mod,l)){ - //CLOSE - NyLPC_OnErrorGoto(Error); - } - va_start(a,i_fmt); - if(!NyLPC_cFormatWriter_print(fmt_handler,NyLPC_cHttpdConnection_refStream(this->_mod->_ref_connection),i_fmt,a)){ - va_end(a); - NyLPC_OnErrorGoto(Error); - } - va_end(a); - NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(this->_mod->_ref_connection)); - return true; - Error: - NyLPC_cHttpdConnection_closeSocket(this->_mod->_ref_connection); - this->_mod->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED; - return false; + return ret; } int ModWebSocket::read(void* i_rx_buf,int i_rx_size)
--- a/mbed/mod/ModWebSocket.h Tue Jun 10 03:30:41 2014 +0000 +++ b/mbed/mod/ModWebSocket.h Fri Jun 13 11:06:33 2014 +0000 @@ -21,7 +21,6 @@ class ModWebSocket:ModBaseClass { private: - const Net* _ref_net; protected: NyLPC_TcModWebSocket_t* _mod; public: @@ -49,7 +48,7 @@ * @param ... * argument list for i_fmt */ - bool writeF(const char* i_fmt,...); + bool writeFormat(const char* i_fmt,...); /** * This function receives data from websocket stream.