[[← 6 節に戻る|Palm OS Programmer's Companion Volume II/5-6]] [[↑5 章トップへ|Palm OS Programmer's Companion Volume II/5]] [[8 節に進む →|Palm OS Programmer's Companion Volume II/5-8]] ---- !!! 5-7 シリアルリンクマネージャ   シリアルリンクマネージャは、シリアルリンクプロトコルの Palm OS 実装です。 シリアルリンクマネージャは複数のクライアントソケット、パケット送信、同期/非同期のパケット受信、を管理するメカニズムを提供します。また、リモートデバッガまたはリモートプロシージャコール( Remote Procedure Calls : RPC )のサポートも提供します。 !!シリアルリンクマネージャの利用 アプリケーションがシリアルリンクマネージャのサービスを利用する前に、アプリケーションは {{span style='color:blue;font-family:monospace;',SlkOpen}} をコールしてマネージャを開かなければいけません。エラーコードがゼロまたは {{span style='color:blue;font-family:monospace;',slkErrAlreadyOpen}} であれば、成功です。戻り値 {{span style='color:blue;font-family:monospace;',slkErrAlreadyOpen}} は、シリアルリンクマネージャが既に(たいていは他のタスクによって)開いていることを示します。他のエラーコードは失敗を示します。 シリアルリンクマネージャの利用が終わったら、{{span style='color:blue;font-family:monospace;',SlkOpen}} をコールしてゼロまたは {{span style='color:blue;font-family:monospace;',slkErrAlreadyOpen}} が戻されます。開く数がゼロに達したら、{{span style='color:blue;font-family:monospace;',SlkOpen}} によってアロケートされたリソースを {{span style='color:blue;font-family:monospace;',SlkClose}}が解放します。 シリアルリンクマネージャのソケットサービスを利用するには、[[「ソケットIDの割り当て」]]をコールしてシリアルリンクソケットを開きます。 シリアルリンクソケットを使い終わったら、{{span style='color:blue;font-family:monospace;',SlkCloseSocket}} をコールしてそれを閉じます。これは、シリアルリンクマネージャによってこのソケットにアロケートされたシステムリソースを解放します。 特定のソケットのために通信ライブラリの参照値を得るには、{{span style='color:blue;font-family:monospace;',SlkSocketRefNum}} をコールします。そのソケットは既に開いている必要があります。ソケットのためにポート ID を得るには、もしシリアルマネージャを使っているなら、{{span style='color:blue;font-family:monospace;',SlkSocketPortID}} をコールします。 特定のソケットのためにバイト内パケットの受信タイムアウトを設定するには、{{span style='color:blue;font-family:monospace;',SlkSocketSetTimeout}} をコールします。 特定のソケットのために受信ストリームをフラッシュするには、ソケットの値とそのバイト内タイムアウトを渡して {{span style='color:blue;font-family:monospace;',SlkFlushSocket}} をコールします。 特定のソケットのためにソケットリスナを登録するには、開いたソケットのソケット値と {{span style='color:blue;font-family:monospace;',SlkSocketListenType}} 構造体へのポインタを渡して {{span style='color:blue;font-family:monospace;',SlkSetSocketListener}} をコールします。シリアルリンクマネージャは {{span style='color:blue;font-family:monospace;',SlkSocketListenType}} 構造体をコピーしませんが、代わりに渡されたポインタを保存します。そのため、その構造体は自動変数(つまりスタックにアロケートされるもの)にはなりません。{{span style='color:blue;font-family:monospace;',SlkSocketListenType}} 構造体はアプリケーションのグローバル変数かもしれませんし、またはダイナミックヒープからアロケートされたロックされたチャンクかもしれません。{{span style='color:blue;font-family:monospace;',SlkSocketListenType}} 構造体はソケットリスナプロシージャへのポインタとこのソケットに向いたディスパッチ中のパケットのためのデータバッファを指定します。2 つのバッファへのポインタは指定されるべきです。 *パケットヘッダバッファ( {{span style='color:blue;font-family:monospace;',SlkPktHeaderType}}のサイズ) *パケットボディバッファ。これは、予想されるクライアントデータサイズよりも充分に大きくなければいけません。 両バッファはアプリケーションのグローバル変数かもしれませんし、またはダイナミックヒープからアロケートされたロックされたチャンクかもしれません。 ソケットリスナプロシージャは、有効なパケットがソケットに受信されたときにコールされます。パケットヘッダバッファとパケットボディバッファへのポインタは、ソケットリスナプロシージャのパラメータとして渡されます。シリアルリンクマネージャは、ソケットが閉じるときに {{span style='color:blue;font-family:monospace;',SlkSocketListenType}} 構造体やバッファを解放しません。つまり、それらの解放はアプリケーションの責任で行なうものです。この関数のメカニズムにより、定期的に {{span style='color:blue;font-family:monospace;',SlkReceivePacket}} をコールすることによるシリアルリンクマネージャ受信者を「運用する」責任を引き受けるためにはいくつかのタスクが要求されます。 パケットを送信するには、このセクションで説明したプロセスを取り入れた Listing 5.12 をコールします。 '''Listing 5.12 シリアルリンクパケットの送信''' Err err; //serial link packet header SlkPktHeaderType sendHdr; //serial link write data segments SlkWriteDataType writeList[2]; //packet body(example packet body) UInt8 body[20]; // Initialize packet body ... // Compose the packet header. Let Serial Link Manager // set the transId. sendHdr.dest = slkSocketDLP; sendHdr.src = slkSocketDLP; sendHdr.type = slkPktTypeSystem; sendHdr.transId = 0; // Specify packet body writeList[0].size = sizeof(body); //first data block size writeList[0].dataP = body; //first data block pointer writeList[1].size = 0; //no more data blocks // Send the packet err = SlkSendPacket( &sendHdr, writeList ); ... } '''Listing 5.13 新しいトランザクション ID の生成''' // // Example: Generating a new transaction ID given the // previous transaction ID. Can start with any seed value. // UInt8 NextTransactionID (UInt8 previousTransactionID) { UInt8 nextTransactionID; // Generate a new transaction id, avoid the // reserved values (0x00 and 0xFF) if ( previousTransactionID >= (UInt8)0xFE ) nextTransactionID = 1; // wrap around else nextTransactionID = previousTransactionID + 1; // increment return nextTransactionID; } パケットを受信するには、{{span style='color:blue;font-family:monospace;',SlkReceivePacket}} をコールします。渡されたソケットIDのためだけにパケットを要求するかもしれませんし、もしくはソケットリスナを持たない開いたソケットのためかもしれません。パケットヘッダとクライアントデータとタイムアウトのためのバッファをパラメータで指定します。タイムアウトは、タイムアウトする前に到達を開始するために、受信側がどの程度パケットを待たなければいけないか、を示します。-1 のタイムアウト値は「永久に待つ」を意味します。もし登録されたソケットリスナを持つソケットのためにパケットが受信されるなら、パケットはそのソケットリスナプロシージャを経由してディスパッチされます。   ---- [[← 6 節に戻る|Palm OS Programmer's Companion Volume II/5-6]] [[↑5 章トップへ|Palm OS Programmer's Companion Volume II/5]] [[8 節に進む →|Palm OS Programmer's Companion Volume II/5-8]]