2 * @fileOverview 低レベルAPIを定義する。低レベルAPIは、MiMicRemoteMcuをインストールしたMCUとの通信クラスを提供する。
\r
6 * MiMicが使用する関数、定数を定義する。
\r
12 * MiMicJsAPIのバージョン文字列。
\r
14 VERSION:"MiMicJsAPI/1.0.2",
\r
19 getNow:function getNow(){
\r
20 return (new Date()).getTime();
\r
23 * aがundefinedであるかを真偽値で返す。
\r
28 * aがundefinedであれば、trueである。
\r
30 isUndef:function isUndef(a){
\r
31 return typeof a==="undefined"
\r
39 * aがarrayであれば、trueである。
\r
41 isArray:function isArray(a){
\r
42 return a instanceof Array;
\r
45 * 連想配列をシャローコピーして複製する。
\r
52 cloneAssoc:function cloneAssoc(a)
\r
61 * 桁数を指定して、int値を16進数に変換する。
\r
62 * @param {int} i_val
\r
64 * @param {int} i_digit
\r
69 hexout:function hexout(i_val,i_digit)
\r
72 var dt=["","0","00","000","0000","00000","000000","0000000"];
\r
73 var s=(i_val>>>0).toString(16).toLowerCase();
\r
74 if(s.length>i_digit){
\r
76 throw new MiMicException(EE.NG);
\r
78 var l=i_digit-s.length;
\r
81 throw new MiMicException(e);
\r
84 assocToStr:function assocToStr(a)
\r
87 for(k in a){s+=k+":"+a[k]+",";}
\r
93 * MiMicExceptionが使用するエラーコードと、その判定関数を定義する。
\r
94 * エラーコードは、以下の形式の配列オブジェクトで表現する。
\r
96 * [code:int,message:string]
\r
99 * codeは31ビットのエラーコードである。ビットフィールドの意味は以下の通りである。
\r
101 * <tr><th>bit</th><th>name</th><th>discription</th></tr>
\r
102 * <tr><td>30</td><td>ErrorBit</td><td>Error:1,OK:0</td></tr>
\r
103 * <tr><td>29-24</td><td>Reserved</td><td>-</td></tr>
\r
104 * <tr><td>23-16</td><td>ModuleID</td><td>0x00:unknown<br/>0x39:MiMic<br/>0xF0-0xFF: user define<br/>Other:Reserved<br/></td></tr>
\r
105 * <tr><td>15-8</td><td>ClassID</td><td>0x00:unknown</td></tr>
\r
106 * <tr><td>7-0</td><td>ErrorID</td><td></td></tr>
\r
110 * throw new MiMicException(MiMicError.NG);
\r
116 OK:[0x00000000,"OK"],
\r
117 /** 失敗を示すエラー値。不明な場所で、不明な何かが、不明なエラーを起こしたことを示す。
\r
119 NG:[0x40000000,"NG"],
\r
123 * @param {Object as [MiMicErrorCode]} v
\r
125 * @return {Boolean}
\r
126 * エラーコードでなければ、trueを返す。
\r
128 * MiMicError.isOK(MiMicError.OK);//true
\r
131 return (0x40000000 & v)==0x00000000;
\r
137 MID_MiMic:0x00390000,
\r
139 CAID_RemoteMCU :0x0100, //
\r
141 CAID_LPCXPresso1769:0x0200 //リモートAPI
\r
148 * @name MiMicException.2
\r
150 * @param {object} e
\r
153 * <li>{string} - MiMicException(MiMicError.NG,e)と等価である。</li>
\r
154 * <li>{object as [MiMicErrorCode]} - エラーコードを指定して例外を生成する。エラーコードについては、MiMicErrorを参照</li>
\r
155 * <li>{object} - MiMicException(MiMicError.NG,e.toString())と等価である。objectを文字列化して例外を生成する。</li>
\r
156 * <li>{MiMicException} - codeとmessageを継承して例外を生成する。コールスタックを生成するときは、このパターンを使うこと。</li>
\r
159 * throw new MiMicException(MiMicError.NG);
\r
160 * throw new MiMicException("Error");
\r
162 * throw new MiMicException("Error");
\r
164 * throw new MiMicException(e);
\r
168 * 引数が2個のパターン。追加メッセージを含めることが出来る。
\r
169 * @name MiMicException.3
\r
171 * @param {object} e
\r
174 * <li>{MiMicErrorCode} - エラーコードを指定して例外を生成する。</li>
\r
175 * <li>{MiMicException} - codeとmessageを継承して例外を生成する。コールスタックを生成するときは、このパターンを使うこと。</li>
\r
177 * @param {string} s
\r
181 * MiMic javascript APIが生成する例外クラスのコンストラクタである。関数ごとにMiMicExceptionを使ったtry-catchを導入することにより、例外発生時にスタックトレースメッセージを得ることが出来る。
\r
182 * スタックトレースは改行で連結された文字列である。messageプロパティに格納される。alert関数で表示することで、効率的なデバックが可能である。
\r
183 * 引数の違いにより、数種類の呼び出し方がある。
\r
186 * 詳細は、MiMicException.nを参照。
\r
188 function MiMicException(/*...*/)
\r
191 if(typeof arguments.callee.caller=="function"){
\r
192 if(arguments.callee.caller.name.toString().length>0){
\r
193 pfx="function '"+arguments.callee.caller.name+'.';
\r
195 var s=arguments.callee.caller.toString();
\r
196 pfx="closure '"+s.substring(0,s.indexOf("{"))+"...'";
\r
199 pfx="root document";
\r
202 switch(arguments.length){
\r
205 this.code=MiMicError.NG[0];
\r
206 this.message=pfx+" code(0x"+this.code.toString(16)+")"+MiMicError.NG[1];
\r
209 var v=arguments[0];
\r
210 if(v instanceof MiMicException){
\r
213 sfx=" \nfrom "+v.message;
\r
214 }else if(typeof v=="object" && v.length==2){
\r
220 this.code=MiMicError.NG[0];
\r
221 sfx=MiMicError.NG[1]+" "+(((typeof v)!='undefined')?v.toString():"v==undefined");
\r
223 this.message=pfx+" code(0x"+this.code.toString(16)+")"+sfx;
\r
226 var v=arguments[0];
\r
227 if(v instanceof MiMicException){
\r
230 this.message=pfx+" code(0x"+this.code.toString(16)+")"+"\nfrom "+v.message+":"+arguments[1];
\r
232 }else if(typeof v!="string" && v.length==2){
\r
233 //Errorコードテーブル+メッセージ
\r
235 this.message=pfx+" code(0x"+this.code.toString(16)+")"+v[1]+":"+arguments[1];
\r
243 throw new MiMicException("Invalid MiMicException argument.");
\r
246 MiMicException.prototype={
\r
248 * MiMicErrorCode形式のエラーコードを保持する。
\r
249 * @field {object as MiMicErrorCode}
\r
251 code:MiMicError.OK,
\r
253 * エラーメッセージを保持する。この値は、改行区切りのコールスタックである。
\r
258 * messageフィールドをalertで表示する。
\r
262 * throw new MiMicException();
\r
268 alert(this.message);
\r
271 * toStringを上書きする。オブジェクトを文字列化する。
\r
272 * 文字列は例外のコールスタックであり、デバックで役立つ。
\r
275 * 現在のオブジェクトの状態(例外のコールスタック)
\r
278 * throw new MiMicException();
\r
280 * alert(e.toString());
\r
283 toString:function()
\r
285 return "MiMicException:"+this.message;
\r
297 var MiMicRemoteMcuInterface;
\r
304 var EE=function(i_base)
\r
307 NG:[i_base|0x00,"Unknown exception in MiMicRemoteMcuInterface"],
\r
308 TCP_CONNECT:[i_base|0x01,"TCP CONNECT FAILED"],//接続エラー
\r
309 HTTP :[i_base|0x02,"HTTP FAILED"]}//HTTPエラー
\r
310 }(MiMicError.NG[0]|MiMicError.MID_MiMic|MiMicError.CAID_RemoteMCU);
\r
312 * MiMicRemoteMcuInterfaceクラスのコンストラクタ。
\r
313 * MiMicRemoteMcuInterfaceクラスは、MCUで動作するMiMicRemoteMcuとの通信機能と、接続状態の監視機能を提供する。低レベルAPI全てを実装する。
\r
314 * 低レベルAPIは、MiMicRemoteMcuとの通信を、関数コールに変換する。
\r
315 * インスタンス生成直後は、MiMicRemoteMcuとの接続は断状態である。connect関数を実行して、接続する必要がある。
\r
316 * 通信仕様については、MiMicVM.pdf Appendix 1.MiMicVM HTTP Interfaceを参照すること。
\r
318 * @param {string} i_path
\r
319 * 接続するMiMicRemoteMcuのホストパスを指定します。
\r
320 * MiMicVersion 1.4以降はMiMicサーバの/mvm/に割り当てられています。
\r
321 * ホストアドレスのみを指定した場合、"/mvm/"サフィックスを自動で追加します。
\r
323 * "127.0.0.1" =< "127.0.0.1/mvm/"<br/>
\r
324 * "127.0.0.1:3939/mvm/" =< "127.0.0.1:3939/mvm/"
\r
326 * //create a controlable MCU via network.
\r
327 * var mcu=new MiMicRemoteMcuInterface(“192.168.0.39/mvm/”);
\r
329 MiMicRemoteMcuInterface=function MiMicRemoteMcuInterface(i_path)
\r
331 this._mimic_path=i_path+((i_path.indexOf("/")==-1)?"/mvm/":"");
\r
334 MiMicRemoteMcuInterface.prototype=
\r
341 _last_xhr_res_time:0,
\r
343 * XmlHttpRequestを実行する。
\r
350 _xhrGet:function(i_url,i_async,i_callback)
\r
352 var xhr = window.XDomainRequest ? new XDomainRequest() : new XMLHttpRequest();
\r
356 xhr.onreadystatechange = function(){
\r
357 if (xhr.readyState == 4){
\r
359 this._last_xhr_res_time=MiMicLib.getNow();
\r
364 xhr.open("GET",i_url,i_async);
\r
369 this._last_xhr_res_time=MiMicLib.getNow();
\r
373 throw new MiMicException(
\r
376 case 1:return EE.HTTP;
\r
378 return EE.TCP_CONNECT;
\r
384 * MiMicの応答から、オンラインチェックを実行します。
\r
387 * レスポンスを格納済みのXHRオブジェクト
\r
390 * 入力文章から状態が判定できなかった場合、false
\r
392 _isOnline_parseResponse: function(res)
\r
396 function parse_version_tag(i_v)
\r
398 var t=i_v.split("/");
\r
399 var n=t[1].split(".");
\r
400 return {name:t[0],major:parseInt(n[0]),minor:parseInt(n[1])};
\r
403 //"MiMicRemoteMCU/1.n;xならOK.(n>=1)
\r
404 var l=i_s.split(";");
\r
405 var rmcu=parse_version_tag(l[0]);//ModRemoteMcu
\r
406 var mcut=l[1];//MCUTYPE
\r
407 return ((rmcu.name=="ModRemoteMcu") && (rmcu.major==1) && (rmcu.minor>=0));
\r
409 throw MiMicException(e);
\r
414 if(res.status!=200){
\r
417 var ret=eval("("+res.responseText+")");
\r
418 if(!isok(ret.application)){
\r
427 * MvmのレスポンスをJSOにする。
\r
434 _parseMvmResult:function(i_mvmresult)
\r
438 //ModRemoteMcu/1.x;Json/1.0ならOK
\r
439 var l=i_s.split(";");
\r
440 return((l[0].indexOf("ModRemoteMcu/1.")==0) && (l[1]=="Json/1.0"));
\r
442 var ret=eval("("+i_mvmresult+")");
\r
443 if(isok(ret.version)){
\r
444 if(ret.result!=undefined){
\r
445 if(ret.result!=0x0 || ret.stream!=undefined){
\r
451 throw new MiMicException(EE.NG,"Invalid json version:'"+ret.version+"'");
\r
455 * 接続状態の場合、execBc等の低レベルAPIを使用できる。
\r
456 * 状態は、インスタンスが定期的に実行するプローブ信号でチェックされ、更新される。
\r
458 * @return {boolean}
\r
459 * 接続状態。trueなら、MCUインタフェイスは利用可能。
\r
461 * //show connection status
\r
462 * var mri=new MiMicRemoteMcuInterface(“192.168.0.1”);
\r
463 * alert(mri.isConnected());
\r
465 isConnected:function isConnected()
\r
467 return this._keep_alive!=null;
\r
470 * 接続中のMiMicremoteMCUへ、整形済みのMiMicBCを送信する。
\r
471 * 関数の利用前に、connect関数でMiMicremoteMCUへ接続する必要がある。
\r
472 * 何らかのエラーが発生してMiMicRemoteMCUからの応答が得られない場合、関数は例外を発生する。
\r
473 * この状況は、TCP/IPエラー、HTTPエラー、HTTPステータスエラー、MiMicVMのラインタイムエラー、MiMicRemoteMCUのフォールト等の原因で発生する。<br/>
\r
474 * 関数は同期実行でのため、RemoteMCUが応答しないと制御がブロックする。非同期関数は今後実装する。
\r
476 * @param {string} i_bc
\r
477 * 整形済みのMiMicBC文字列。MiMicBCについては、MiMicVM.pdf の、MiMicBCの章を参照。
\r
479 * MiMicVMのパース済みJavascriptObjectである。
\r
482 * {version: string,result: int,stream int[]}
\r
484 * 詳細は、 MiMicVM.pdf Appendix 1. MiMicVM HTTP Interfaceを参照。
\r
487 * var mri=new MiMicRemoteMcuInterface(“192.168.0.1”);
\r
488 * mri.connect(function(){});
\r
489 * mri.execBc(“ZAZZ.E”);//NOP;EXIT;
\r
491 execBc:function execBc(i_bc)
\r
494 if(this._keep_alive==null){
\r
495 throw new MiMicException(EE.NG,"disconnected");
\r
497 var res=this._xhrGet("http://"+this._mimic_path+"mvm.api?v=1&bc="+i_bc,false);
\r
498 if(res.status!=200){
\r
499 throw new MiMicException(EE.HTTP,"i_bc="+i_bc+",XHR.status="+res.status);
\r
501 return this._parseMvmResult(res.responseText,false);
\r
503 throw new MiMicException(e);
\r
508 * MiMicRemoteMCUへ接続する。
\r
511 * @param {function} i_callback
\r
512 * 回線状態を定期的に通知するコールバックハンドラ。
\r
513 * <pre>function(b:{boolean})</pre>
\r
514 * disconnect関数を呼び出すまでの間、回線の状態を定期的に受け取る。
\r
515 * bは接続状態を表す真偽値である。trueの時、接続中である。falseの場合、外部要因により切断されている。
\r
516 * falseが通知されるのは、disconnectが呼び出されるまでに非同期切断を検出したときだけである。disconnectで切断した場合には呼び出されない。
\r
518 * //show connection status
\r
519 * var mri=new MiMicRemoteMcuInterface(“192.168.0.1”);
\r
520 * mri.connect(function(b){if(!b){alert(“disconnected!”);}});
\r
522 connect:function connect(i_callback)
\r
527 if(this._keep_alive!=null){
\r
530 function xhrStatus(i_is_async,i_cb)
\r
533 return _t._xhrGet("http://"+_t._mimic_path+"status.api",i_is_async,i_cb);
\r
538 function intervalProc()
\r
541 var now=MiMicLib.getNow();
\r
542 //最後に通信に成功した時刻からの経過時間を計算
\r
543 var lt=now-_t._last_xhr_res_time;
\r
547 //最後の通信からの経過時間がNを超えていたら通信チェック
\r
548 var res=xhrStatus(false,null);
\r
549 if((res==null) || (!_t._isOnline_parseResponse(res))){
\r
550 if(_t._keep_alive!=null){
\r
552 clearInterval(_t._keep_alive.tid);
\r
553 _t._keep_alive=null;
\r
560 var res=xhrStatus(false,null);
\r
561 if((res==null) || (!_t._isOnline_parseResponse(res))){
\r
562 throw new MiMicException("Bad response from "+this._mimic_path);
\r
566 tid:setInterval(intervalProc,500)
\r
569 throw new MiMicException(e);
\r
574 * 接続中のMiMicRemoteMCUから切断する。接続されていなければ何もしない。
\r
577 * //connect and disconnect
\r
578 * var mri=new MiMicRemoteMcuInterface(“192.168.0.1”);
\r
579 * mri.connect(function(b){if(!b){alert(“disconnected!”);}});
\r
580 * mri.disconnect();
\r
582 disconnect:function disconnect()
\r
585 if(this._keep_alive!=null){
\r
586 clearInterval(this._keep_alive.tid);
\r
587 this._keep_alive=null;//abortによるコールバックを抑制
\r
590 throw new MiMicException(e);
\r