OSDN Git Service

update libMiMic
[mimic/MiMicSDK.git] / lib / src / net / httpd / mod / NyLPC_cModRemoteMcu.c
1 /*********************************************************************************\r
2  * PROJECT: MiMic\r
3  * --------------------------------------------------------------------------------\r
4  *\r
5  * This file is part of MiMic\r
6  * Copyright (C)2011 Ryo Iizuka\r
7  *\r
8  * MiMic is free software: you can redistribute it and/or modify\r
9  * it under the terms of the GNU Lesser General Public License as published\r
10  * by the Free Software Foundation, either version 3 of the License, or\r
11  * (at your option) any later version.\r
12  *\r
13  * This program is distributed in the hope that it will be useful,\r
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
16  * GNU General Public License for more details.\r
17  *\r
18  * You should have received a copy of the GNU Lesser General Public License\r
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
20  *\r
21  * For further information please contact.\r
22  *  http://nyatla.jp/\r
23  *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
24  *\r
25  *********************************************************************************/\r
26 #include "NyLPC_cModRemoteMcu.h"\r
27 #include "NyLPC_stdlib.h"\r
28 #include "NyLPC_http.h"\r
29 #include "NyLPC_mimicVm.h"\r
30 #include "../NyLPC_cHttpdConnection_protected.h"\r
31 #include "../NyLPC_cHttpdUtils.h"\r
32 #include "NyLPC_net.h"\r
33 \r
34 #define MVM_VERSION "ModRemoteMcu/1.0;Json/1.0"\r
35 #define SIZE_OF_IBUF 256\r
36 struct TModMiMicRemoteMcuHeader\r
37 {\r
38     struct NyLPC_THttpBasicHeader super;\r
39     NyLPC_TUInt8 _content_id;\r
40     //解析用\r
41     NyLPC_TUInt8 _qery_name_id;\r
42     NyLPC_TUInt8 _astate;\r
43     NyLPC_TInt16 _prefix_len;\r
44     NyLPC_TcStr_t _tstr;\r
45     NyLPC_TChar _tstr_buf[16];\r
46     struct NyLPC_TUInt32ArrayPtr _binarray;\r
47     /** 文字列のパーサ*/\r
48     NyLPC_TcMiMicDbCompiler_t _binparser;\r
49     NyLPC_TcMiMicTxtCompiler_t _txtcmp;\r
50     union{\r
51         struct{\r
52             NyLPC_TUInt8 v;//バージョン\r
53             NyLPC_TUInt8 o;//outputスタイル\r
54             /**\r
55              * il_bufはbcとdbの2パートのデータを格納します。\r
56              * 先頭からbc_lenの長さのBCパートと、db_partからdb_lenの長さのデータです。\r
57              */\r
58             struct{\r
59                 /** MiMicVMインストラクションの蓄積用。前半にTXT,後半にDBを格納する。 */\r
60                 NyLPC_TUInt32 bc_buf[SIZE_OF_IBUF];\r
61                 /** MiMicVM入力ストリーム(MimicDB)の開始位置(bufの一部を指す) */\r
62                 const NyLPC_TUInt32* db_part;\r
63                 /** MiMicTXTのワード長(1ワード32bit)*/\r
64                 NyLPC_TUInt16 txt_len;\r
65                 /** MiMicDBのワード長(1ワード32bit)*/\r
66                 NyLPC_TUInt16 db_len;\r
67             }vm_instruction;\r
68         }mvm;\r
69         struct{\r
70             /**\r
71              * 不明な名前の場合は、ここに名前をコピー\r
72              */\r
73             NyLPC_TChar path[32];\r
74         }unknown;\r
75     }content;\r
76 };\r
77 \r
78 \r
79 static void mvm(NyLPC_TcHttpdConnection_t* i_connection,const struct TModMiMicRemoteMcuHeader* i_rqh);\r
80 static void status(NyLPC_TcHttpdConnection_t* i_connection);\r
81 \r
82 \r
83 \r
84 \r
85 #define ST_PARSE_PATH 1\r
86 #define ST_PARSE_QUERY_NAME 2\r
87 #define ST_PARSE_QUERY_VALUE 3      //Query読み出し中\r
88 #define ST_PARSE_QUERY_VALUE_V 4\r
89 #define ST_PARSE_QUERY_VALUE_O 5\r
90 #define ST_PARSE_QUERY_VALUE_BC 6\r
91 #define ST_PARSE_QUERY_VALUE_DB 7\r
92 /**\r
93  * コンテンツID定義(コンテンツ名に対応)\r
94  */\r
95 #define CONTENT_ID_MVM   2\r
96 #define CONTENT_ID_STATUS  3\r
97 #define CONTENT_ID_UNKNOWN 0\r
98 \r
99 \r
100 #define QNAME_ID_V  1\r
101 #define QNAME_ID_O  2\r
102 #define QNAME_ID_BC 3\r
103 #define QNAME_ID_UNKNOWN 0\r
104 \r
105 /**\r
106  * TRemoteMcuRequest.content.mvm.oの値\r
107  */\r
108 #define QVAL_O_UNKNOWN 0    //default\r
109 #define QVAL_O_XML     1\r
110 #define QVAL_O_JSON    2\r
111 \r
112 #define QVAL_V_UNKNOWN  0\r
113 #define QVAL_V_1        1\r
114 \r
115 \r
116 static const struct NyLPC_TTextIdTbl url_tbl[]=\r
117 {\r
118     {"mvm.api",CONTENT_ID_MVM},\r
119     {"status.api",CONTENT_ID_STATUS},\r
120     {NULL,CONTENT_ID_UNKNOWN}\r
121 };\r
122 \r
123 static const struct NyLPC_TTextIdTbl qname_id_table[]=\r
124 {\r
125     {"o",QNAME_ID_O},\r
126     {"bc",QNAME_ID_BC},\r
127     {"v",QNAME_ID_V},\r
128     {NULL,QNAME_ID_UNKNOWN}\r
129 };\r
130 \r
131 \r
132 \r
133 static NyLPC_TBool urlHandler(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out)\r
134 {\r
135     NyLPC_TUInt16 ol;\r
136     struct TModMiMicRemoteMcuHeader* out=(struct TModMiMicRemoteMcuHeader*)o_out;\r
137     //読み飛ばし\r
138     if(out->_prefix_len<0){\r
139         out->_prefix_len++;\r
140         return NyLPC_TBool_TRUE;//読み飛ばし\r
141     }\r
142     if(out->_astate==ST_PARSE_PATH){\r
143         if(i_c!='\0' && i_c!='?'){\r
144             if(!NyLPC_cStr_put(&(out->_tstr),i_c)){\r
145                 //ERROR\r
146                 NyLPC_OnErrorGoto(ERROR);\r
147             }\r
148         }else{\r
149             out->_content_id=NyLPC_TTextIdTbl_getMatchId(NyLPC_cStr_str(&(out->_tstr)),url_tbl);\r
150             switch(out->_content_id)\r
151             {\r
152             case CONTENT_ID_MVM:\r
153                 out->content.mvm.vm_instruction.txt_len=0;\r
154                 out->content.mvm.vm_instruction.db_len=0;\r
155                 out->content.mvm.vm_instruction.db_part=NULL;\r
156                 NyLPC_TUInt32ArrayPtr_setBuf(&out->_binarray,out->content.mvm.vm_instruction.bc_buf,SIZE_OF_IBUF);\r
157                 out->content.mvm.o=QVAL_O_JSON;\r
158                 out->content.mvm.v=QVAL_V_UNKNOWN;\r
159                 break;\r
160             default:\r
161                 break;\r
162             }\r
163             NyLPC_cStr_clear(&(out->_tstr));\r
164             out->_astate=ST_PARSE_QUERY_NAME;//クエリ名解析へ\r
165         }\r
166         return NyLPC_TBool_TRUE;\r
167     }\r
168     switch(out->_content_id)\r
169     {\r
170     case CONTENT_ID_MVM:\r
171         switch(out->_astate){\r
172         case ST_PARSE_QUERY_NAME:\r
173             if(i_c!='\0' && i_c!='&' && i_c!='='){\r
174                 if(!NyLPC_cStr_put(&(out->_tstr),i_c)){\r
175                     NyLPC_OnErrorGoto(ERROR);\r
176                 }\r
177             }else{\r
178                 //Query確定。\r
179                 out->_qery_name_id=NyLPC_TTextIdTbl_getMatchId(NyLPC_cStr_str(&(out->_tstr)),qname_id_table);\r
180                 NyLPC_cStr_clear(&(out->_tstr));\r
181                 //クエリ値がある場合\r
182                 switch(out->_qery_name_id){\r
183                 case QNAME_ID_O:\r
184                     out->_astate=ST_PARSE_QUERY_VALUE_O;//MIMICBCのDBパラメータパーサを借用。\r
185                     break;\r
186                 case QNAME_ID_V:\r
187                     out->_astate=ST_PARSE_QUERY_VALUE_V;\r
188                     break;\r
189                 case QNAME_ID_BC:\r
190                     out->_astate=ST_PARSE_QUERY_VALUE_BC;\r
191                     break;\r
192                 default:\r
193                     out->_astate=ST_PARSE_QUERY_VALUE;\r
194                     break;\r
195                 }\r
196             }\r
197             return NyLPC_TBool_TRUE;\r
198         case ST_PARSE_QUERY_VALUE:\r
199             //未知のクエリは無視\r
200             if(i_c!='\0' && i_c!='&'){\r
201             }else{\r
202                 //クエリ値解析完了\r
203                 out->_astate=ST_PARSE_QUERY_NAME;\r
204             }\r
205             return NyLPC_TBool_TRUE;\r
206         case ST_PARSE_QUERY_VALUE_O:\r
207             if(i_c!='\0' && i_c!='&'){\r
208                 if(!NyLPC_cStr_put(&(out->_tstr),i_c)){\r
209                     NyLPC_OnErrorGoto(ERROR);\r
210                 }\r
211             }else{\r
212                 if(NyLPC_cStr_isEqual(&(out->_tstr),"j")){\r
213                     out->content.mvm.o=QVAL_O_JSON;\r
214                 }else if(NyLPC_cStr_isEqual(&(out->_tstr),"x")){\r
215                     out->content.mvm.o=QVAL_O_XML;\r
216                 }\r
217                 out->_astate=ST_PARSE_QUERY_NAME;\r
218                 NyLPC_cStr_clear(&(out->_tstr));\r
219             }\r
220             return NyLPC_TBool_TRUE;\r
221         case ST_PARSE_QUERY_VALUE_V:\r
222             if(i_c!='\0' && i_c!='&'){\r
223                 if(!NyLPC_cStr_put(&(out->_tstr),i_c)){\r
224                     NyLPC_OnErrorGoto(ERROR);\r
225                 }\r
226             }else{\r
227                 if(NyLPC_cStr_isEqual(&(out->_tstr),"1")){\r
228                     out->content.mvm.v=QVAL_V_1;\r
229                 }\r
230                 out->_astate=ST_PARSE_QUERY_NAME;\r
231                 NyLPC_cStr_clear(&(out->_tstr));\r
232             }\r
233             return NyLPC_TBool_TRUE;\r
234         case ST_PARSE_QUERY_VALUE_BC:\r
235             if(i_c!='\0' && i_c!='&'){\r
236                 //コンパイル\r
237                 switch(NyLPC_cMiMicTxtCompiler_compileFragment2(&(out->_txtcmp),i_c,&(out->_binarray),&ol))\r
238                 {\r
239                 case NyLPC_TcMiMicTxtCompiler_RET_OK:\r
240                     //命令確定。\r
241                     break;\r
242                 case NyLPC_TcMiMicTxtCompiler_RET_OK_END:\r
243                     //命令終端検出->モード切替\r
244                     out->content.mvm.vm_instruction.txt_len=SIZE_OF_IBUF-out->_binarray.len+ol;\r
245                     out->content.mvm.vm_instruction.db_part=out->content.mvm.vm_instruction.bc_buf+out->content.mvm.vm_instruction.txt_len;\r
246                     out->_astate=ST_PARSE_QUERY_VALUE_DB;\r
247                     break;\r
248                 case NyLPC_TcMiMicTxtCompiler_RET_CONTINUE:\r
249                     //何もしない\r
250                     break;\r
251                 case NyLPC_TcMiMicTxtCompiler_RET_NG:\r
252                 default:\r
253                     //ERROR\r
254                     NyLPC_OnErrorGoto(ERROR);\r
255                 }\r
256             }\r
257             return NyLPC_TBool_TRUE;\r
258 //          //フラグメント終端が検出できない終了はエラー\r
259 //          NyLPC_OnErrorGoto(ERROR);\r
260         case ST_PARSE_QUERY_VALUE_DB:\r
261             if(i_c!='\0' && i_c!='&'){\r
262                 switch(NyLPC_cMiMicDbCompiler_compileFragment2(&(out->_binparser),i_c,out->_binarray.ptr))\r
263                 {\r
264                 case NyLPC_TcMiMicDbCompiler_RET_CONTINUE:\r
265                     break;\r
266                 case NyLPC_TcMiMicDbCompiler_RET_OK:\r
267                     //\r
268                     if(!NyLPC_TUInt32ArrayPtr_seek(&(out->_binarray),1)){\r
269                         //ERROR\r
270                         NyLPC_OnErrorGoto(ERROR);\r
271                     }\r
272                     break;\r
273                 case NyLPC_TcMiMicDbCompiler_RET_ERROR:\r
274                 default:\r
275                     //ERROR\r
276                     NyLPC_OnErrorGoto(ERROR);\r
277                 }\r
278             }else{\r
279                 //区切りのいいところで終わってる?\r
280                 if(NyLPC_cMiMicDbCompiler_hasFragment(&(out->_binparser))){\r
281                     //ERROR\r
282                     NyLPC_OnErrorGoto(ERROR);\r
283                 }\r
284                 out->content.mvm.vm_instruction.db_len=((NyLPC_TUInt8*)(out->_binarray.ptr)-(NyLPC_TUInt8*)(out->content.mvm.vm_instruction.db_part))/sizeof(NyLPC_TUInt32);\r
285 \r
286                 //終端しているなら、次のクエリへ\r
287                 out->_astate=ST_PARSE_QUERY_NAME;\r
288             }\r
289             return NyLPC_TBool_TRUE;\r
290         default:\r
291             break;\r
292         }\r
293         NyLPC_OnErrorGoto(ERROR);\r
294     default:\r
295         NyLPC_OnErrorGoto(ERROR);\r
296     }\r
297     return NyLPC_TBool_TRUE;\r
298 ERROR:\r
299     return NyLPC_TBool_FALSE;\r
300 }\r
301 /**\r
302  * デフォルトハンドラ\r
303  */\r
304 static const struct NyLPC_TcHttpBasicHeaderParser_Handler handler=\r
305 {\r
306     NULL,\r
307     urlHandler\r
308 };\r
309 \r
310 \r
311 /**\r
312  * コンストラクタ。\r
313  */\r
314 void NyLPC_cModRemoteMcu_initialize(NyLPC_TcModRemoteMcu_t* i_inst,const NyLPC_TChar* i_ref_root_path)\r
315 {\r
316     NyLPC_cModRomFiles_initialize(&i_inst->super,i_ref_root_path,NULL,0);\r
317 }\r
318 void NyLPC_cModRemoteMcu_finalize(NyLPC_TcModRemoteMcu_t* i_inst)\r
319 {\r
320     NyLPC_cModRomFiles_finalize(&i_inst->super);\r
321 }\r
322 /**\r
323  * モジュールがコネクションをハンドリングできるかを返します。\r
324  */\r
325 NyLPC_TBool NyLPC_cModRemoteMcu_canHandle(NyLPC_TcModRemoteMcu_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection)\r
326 {\r
327     return NyLPC_cModRomFiles_canHandle(&i_inst->super,i_connection);\r
328 }\r
329 \r
330 static struct TModMiMicRemoteMcuHeader single_header;\r
331 \r
332 /**\r
333  * モジュールを実行します。\r
334  */\r
335 NyLPC_TBool NyLPC_cModRemoteMcu_execute(NyLPC_TcModRemoteMcu_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection)\r
336 {\r
337     NyLPC_TcHttpBasicHeaderParser_t parser;\r
338     NyLPC_TUInt8 method_type;\r
339     //リクエストParse済へ遷移(この関数の後はModが責任を持ってリクエストを返却)\r
340     NyLPC_cHttpdConnection_setReqStatusParsed(i_connection);\r
341 \r
342 \r
343     //VM起動の為の排他ロック\r
344     NyLPC_cHttpdConnection_lock(i_connection);\r
345 \r
346 \r
347     //URL解析の準備\r
348     single_header._prefix_len=-((NyLPC_TInt16)strlen(i_inst->super._ref_root_path)+2);\r
349     single_header._astate=ST_PARSE_PATH;\r
350     NyLPC_cStr_initialize(&single_header._tstr,single_header._tstr_buf,16);\r
351     NyLPC_cMiMicDbCompiler_initialize(&single_header._binparser);\r
352     NyLPC_cMiMicTxtCompiler_initialize(&single_header._txtcmp);\r
353 \r
354     NyLPC_cHttpBasicHeaderParser_initialize(&parser,&handler);\r
355 \r
356 \r
357     //プリフェッチしたデータを流す\r
358     NyLPC_cHttpBasicHeaderParser_parseInit(&parser,&(single_header.super));\r
359     NyLPC_cHttpdConnection_pushPrefetchInfo(i_connection,&parser,&single_header.super);\r
360     //後続をストリームから取り込む\r
361     if(!NyLPC_cHttpBasicHeaderParser_parseStream(&parser,NyLPC_cHttpdConnection_refStream(i_connection),&(single_header.super))){\r
362         NyLPC_cHttpdUtils_sendErrorResponse(i_connection,500);\r
363         NyLPC_OnErrorGoto(Error1);\r
364     }\r
365     if(!NyLPC_cHttpBasicHeaderParser_parseFinish(&parser,&(single_header.super))){\r
366         NyLPC_cHttpdUtils_sendErrorResponse(i_connection,500);\r
367         NyLPC_OnErrorGoto(Error1);\r
368     }\r
369     //GETかHEADに制限\r
370     method_type=NyLPC_cHttpdConnection_getMethod(i_connection);\r
371     if(method_type!=NyLPC_THttpMethodType_GET && method_type!=NyLPC_THttpMethodType_HEAD)\r
372     {\r
373         NyLPC_cHttpdUtils_sendErrorResponse(i_connection,405);\r
374         NyLPC_OnErrorGoto(Error1);\r
375     }\r
376     //Request::ConnectionがClose設定,又はHTTP1.1では無い場合,CLOSE\r
377     if(single_header.super.connection==NyLPC_THttpMessgeHeader_Connection_CLOSE || single_header.super.startline.req.version!=NyLPC_THttpVersion_11)\r
378     {\r
379         NyLPC_cHttpdConnection_setConnectionMode(i_connection,NyLPC_TcHttpdConnection_CONNECTION_MODE_CLOSE);\r
380     }\r
381     //CGIの実行\r
382     switch(single_header._content_id)\r
383     {\r
384     case CONTENT_ID_MVM:\r
385         mvm(i_connection,&single_header);\r
386         break;\r
387     case CONTENT_ID_STATUS:\r
388         status(i_connection);\r
389         break;\r
390     default:\r
391         NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400);\r
392         NyLPC_OnErrorGoto(Error1);\r
393     }\r
394     NyLPC_cStr_finalize(&single_header._tstr);\r
395     NyLPC_cMiMicDbCompiler_finalize(&single_header._binparser);\r
396     NyLPC_cMiMicTxtCompiler_finalize(&single_header._txtcmp);\r
397     NyLPC_cHttpBasicHeaderParser_finalize(&parser);\r
398 //占有解除\r
399     NyLPC_cHttpdConnection_unlock(i_connection);\r
400     return NyLPC_TBool_TRUE;\r
401 Error1:\r
402     NyLPC_cStr_finalize(&single_header._tstr);\r
403     NyLPC_cMiMicDbCompiler_finalize(&single_header._binparser);\r
404     NyLPC_cMiMicTxtCompiler_finalize(&single_header._txtcmp);\r
405     NyLPC_cHttpBasicHeaderParser_finalize(&parser);\r
406     //VM排他ロックの解除\r
407     NyLPC_cHttpdConnection_unlock(i_connection);\r
408     return NyLPC_TBool_FALSE;\r
409 }\r
410 \r
411 \r
412 /**\r
413  * イベントハンドラを継承\r
414  */\r
415 struct TVmEventHandler\r
416 {\r
417     struct NyLPC_TcMiMicVM_TEvent super;\r
418     const struct TModMiMicRemoteMcuHeader* req;\r
419     NyLPC_TcHttpdConnection_t* connection;\r
420     NyLPC_TUInt16 db_pos;\r
421     /** ストリームへ出力したデータの数*/\r
422     NyLPC_TUInt16 st_len;\r
423     /** Bodyを送信するかのフラグ*/\r
424     NyLPC_TBool is_send_body;\r
425 };\r
426 \r
427 /**\r
428  * ストリームハンドラ(put)\r
429  */\r
430 static NyLPC_TBool mvmputs_json(struct NyLPC_TcMiMicVM_TEvent* i_eh,NyLPC_TUInt32 i_val)\r
431 {\r
432     struct TVmEventHandler* eh=(struct TVmEventHandler*)i_eh;\r
433     if(eh->is_send_body){\r
434         if(eh->st_len>0){\r
435             eh->st_len++;\r
436             return NyLPC_cHttpdConnection_sendResponseBodyF(eh->connection,",%u",i_val);\r
437         }else{\r
438             eh->st_len++;\r
439             return NyLPC_cHttpdConnection_sendResponseBodyF(eh->connection,"%u",i_val);\r
440         }\r
441     }\r
442     return NyLPC_TBool_TRUE;\r
443 }\r
444 \r
445 /**\r
446  * ストリームハンドラ(get)\r
447  */\r
448 static NyLPC_TBool mvmgets(struct NyLPC_TcMiMicVM_TEvent* i_eh,NyLPC_TUInt32* o_val)\r
449 {\r
450     struct TVmEventHandler* eh=(struct TVmEventHandler*)i_eh;\r
451     //読み出し済みDBサイズの確認\r
452     if(eh->req->content.mvm.vm_instruction.db_len<=eh->db_pos){\r
453         //読めない\r
454         return NyLPC_TBool_FALSE;\r
455     }\r
456     *o_val=eh->req->content.mvm.vm_instruction.db_part[eh->db_pos];\r
457     eh->db_pos++;\r
458     return NyLPC_TBool_TRUE;\r
459 }\r
460 /**\r
461  * ネイティブCALLハンドラ\r
462  */\r
463 static NyLPC_TUInt32 nativeCall(struct NyLPC_TcMiMicVM_TEvent* i_evh,NyLPC_TUInt32 i_id,NyLPC_TcMiMicVM_t* i_vm)\r
464 {\r
465     (void)i_evh;\r
466 //  NyLPC_TNativeFunction f=getNativeFunctionById(i_id);\r
467 //  if(f==NULL){\r
468 //      return NyLPC_cMiMicVM_RESULT_RUNTIME_NG_UNKNOWN_CALL;\r
469 //  }\r
470 //  return f(i_vm)?NyLPC_cMiMicVM_RESULT_OK:NyLPC_cMiMicVM_RESULT_RUNTIME_NG_CALL;\r
471     return NyLPC_cMiMicVM_RESULT_RUNTIME_NG_CALL;\r
472 }\r
473 \r
474 \r
475 static void mvmsleep(struct NyLPC_TcMiMicVM_TEvent* i_eh,NyLPC_TUInt32 i_sleep_in_msec)\r
476 {\r
477     (void)i_eh;\r
478     NyLPC_cThread_sleep(i_sleep_in_msec);\r
479 }\r
480 \r
481 /**\r
482  * RemoteMCUのステータスを返す。基本的にjson\r
483  * {\r
484  *  application:"[VERSION]"\r
485  * }\r
486  */\r
487 static void status(NyLPC_TcHttpdConnection_t* i_connection)\r
488 {\r
489     if(!NyLPC_cHttpdUtils_sendJsonHeader(i_connection)){\r
490         return;\r
491     }\r
492     //JSONを書く。\r
493     if(NyLPC_cHttpdConnection_getMethod(i_connection)==NyLPC_THttpMethodType_GET){\r
494         NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,"{\"application\":\""MVM_VERSION"\"}");\r
495     }\r
496     return;\r
497 }\r
498 /**\r
499  * MimicVMの起動と,ResponseJSONの起動\r
500  * @return\r
501  * 持続性接続を継続するかの真偽値\r
502  */\r
503 static void mvm(NyLPC_TcHttpdConnection_t* i_connection,const struct TModMiMicRemoteMcuHeader* i_rqh)\r
504 {\r
505     struct TVmEventHandler he;\r
506     NyLPC_TcMiMicVM_t vm;\r
507     NyLPC_TUInt32 vmret;\r
508     if(i_rqh->content.mvm.v!=QVAL_V_1 || i_rqh->content.mvm.o!=QVAL_O_JSON)\r
509     {\r
510         NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400);\r
511         return;\r
512     }\r
513 \r
514     //Bodyを書く\r
515     //ハンドラインスタンスの設定\r
516     if(!NyLPC_cHttpdUtils_sendJsonHeader(i_connection)){\r
517         NyLPC_OnErrorGoto(Error1);\r
518     }\r
519 \r
520     he.super.get_stream=mvmgets;\r
521     he.super.put_stream=mvmputs_json;\r
522     he.super.native_call=nativeCall;\r
523     he.super.sleep=mvmsleep;\r
524     he.db_pos=0;\r
525     he.st_len=0;\r
526     he.connection=i_connection;\r
527     he.req=i_rqh;\r
528     he.is_send_body=(NyLPC_cHttpdConnection_getMethod(i_connection)==NyLPC_THttpMethodType_GET);\r
529 \r
530     //起動VMの初期化\r
531     NyLPC_cMiMicVM_initialize(&vm,(struct NyLPC_TcMiMicVM_TEvent*)&(he.super));\r
532 \r
533     //JSONを書く。\r
534     if(he.is_send_body){\r
535         if(!NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,"{\"version\":\""MVM_VERSION"\",\"stream\":[")){\r
536             NyLPC_OnErrorGoto(Error1);\r
537         }\r
538     }\r
539     //VMの実行\r
540     vmret=NyLPC_cMiMicVM_run(&(vm),i_rqh->content.mvm.vm_instruction.bc_buf,i_rqh->content.mvm.vm_instruction.txt_len);\r
541     //only GET method\r
542     if(he.is_send_body){\r
543         if(!NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,"],\"result\":%u}",vmret)){\r
544             NyLPC_OnErrorGoto(Error1);\r
545         }\r
546     }\r
547     NyLPC_cMiMicVM_finalize(&vm);\r
548     return;\r
549 Error1:\r
550     NyLPC_cMiMicVM_finalize(&vm);\r
551     return;\r
552 }\r
553 \r