OSDN Git Service

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