OBEXライブラリ
version 0.00β10
〜 ReadMe 〜
評価版
Copyright(C) 2002-2008 by KEI SAKAKI.
ALL RIGHTS RESERVED.

目次

はじめに

この配布パッケージに含まれるドキュメントおよびソフトウェアはWindows上のJavaにて赤外線およびTCP/IPによるOBEXプロトコル制御を行うためものです。主としてNTTドコモ向け携帯電話である504i/505i/FOMAシリーズとOBEXプロトコルによる赤外線通信を行うために必要な機能を中心に実装しています。

信頼性評価は一般的な基準を満たすほどに行っていません。位置付けは評価用状態となっています。

使用条件

配布パッケージに含まれる全てのドキュメントおよびソフトウェアは以下の条件を全て満たす場合に限って使用することができます。

  1. 使用目的はこのソフトウェアの評価目的に限ります。その他の目的に転用することはできません。
  2. 配布パッケージは自己責任によってのみ使用することができます。使用した結果何らかの損害を生じたとしても作者(さかきけい)は一切責任を負いません。
  3. この配布パッケージ全体および一部をいかなる手段を用いても転載および再配布することを禁じます。
  4. 配布パッケージの所有権および著作権他、全ての権利は作者(さかきけい)が保持しています。使用者に対して各種権利等が移転することはありません。

動作環境

このOBEXライブラリは赤外線通信部分にネイティブコードを含んでいるため、該当する処理はWindows2000/XPおよび98/98SE/Meでのみ動作します。作者はWindowsXPで動作確認を行っていることから、その他の環境では正常に動作しない可能性があります。

その他の動作条件については以下の通りです。なお、赤外線通信を行わないのであれば、環境を問わずJava 1.1以降で動作するはずですが、実際の動作テストはJava SE 6でのみ行っています。

必須動作環境
OSWindows2000/XPを推奨、Windows98/98SE/Meでも動作すると思われます。
Java実行環境Java 1.1をフルスペックでサポートするWindows上のJava VM
Microsoft VM for Java Build 3154以降(それ以前は不可)
IrDAデバイスWindowsがIrDAデバイスとして認識するもの(CIRおよびConsumer IRとして認識されているものは不可)。

作者は以下の環境で動作確認を行いました。

作者の動作確認環境
OSWindows XP Professional / Service Pack 2
Java実行環境Java SE 1.6.0_07のみ
IrDAデバイスリンク・エボリューション製 IrSTICK(旧Sigmatel Inc社製チップ採用)
株式会社クエスト製 USB IrDA(KC Technology, Inc社製チップ採用)
マシンIntel D875PBZ / Pentium 4 630 / RAM 2GB
赤外線対応機器504i各機種および504iS各機種、505i〜506iSの一部、FOMA P2101V/N2051/F2051/P2102V、FOMA 900i〜905iシリーズの一部、PalmIIIc、その他

使用方法

配布パッケージに含まれている obexlib.jarCLASSPATH に設定し、 ksjobex.dllPATH の検索対象に含めてください。以上で使用できるようになります。

また使用に際しては競合するソフトウェアを停止する必要があります。例えばWindows2000/XPではデフォルトでInfrared Monitorサービスが動作していますので、これを停止する必要があります。

OBEXの実装状態

APIの概要

この赤外線OBEX通信APIはNTTドコモが規定するDoJa-3.0(DoCoMoProfile-3.0)に概ね合わせつつ拡張したものとしています。DoCoMoProfile-3.0では、同社の携帯電話でのみ必要とする機能を定義していますが、Java SE において大量のデータを扱う際に問題となりうる部分があります。その部分を中心に仕様を拡張を行いました。詳しくはこの配布パッケージに付属しているAPIリファレンスを参照してください。

なお、通信の相手はIrDAによる赤外線通信のほかにTCP/IPによる通信も可能です。赤外線デバイスが手元に無い場合およびTCP/IPベースのOBEXプロトコル通信が必要な際に有用です。IANAはOBEXプロトコルに対してポート番号650を割り当てています。

サンプルアプリケーション

obex

obexはコマンドラインベースのJavaアプリケーションで、指定されたオペレーションを赤外線OBEX通信APIを経由して実行するためのインターフェースを提供します。実行可能なオペレーションは PUTGETSERVER です。このうち PUTGET は実際のOBEXオペレーションを指し、 SERVER はサーバーとしてOBEXリクエストを待ち受けるということを指します。

obexのコマンド書式を以下に示します。

ファイルを送信(クライアント)

java obex put [option] [filename]
    -setpath [path]
    -name [name]
    -type [type]
    -verbose
    -address [address]
    -port [port]
    -autoname

ファイルをクライアント側からサーバー側へ送信する際に使用します。送信先は -address および -port オプションで指定します。指定を行わなかった場合は赤外線による通信を行います。ファイル名は一度に複数を指定することができます。 -name オプションを指定した場合、ファイルの送信時には常に指定された名前をNAMEヘッダに付加して送信します。 -autoname オプションを指定した場合はファイル名と同じ名前を NAME ヘッダに付加して送信します。ファイルのタイプを送信したい場合は -type オプションにて指定します。指定されたタイプを TYPE ヘッダにて送信します。送信先のデバイスはこのコマンドの実行よりも前にサーバーとして受信状態にしておく必要があります。

ファイルを取得(クライアント)

java obex get [option] [filename]
    -setpath [path]
    -name [name]
    -type [type]
    -verbose
    -address [address]
    -port [port]
    -autoname

ファイルをクライアント側からサーバー側に要求して受信する際に使用します。要求先は -address および -port オプションで指定します。指定を行わなかった場合は赤外線による通信を行います。ファイルは一度に複数を指定することができます。 -name オプションを指定した場合、ファイルの送信時には常に指定された名前を NAME ヘッダに付加して送信します。 -autoname オプションを指定した場合はファイル名と同じ名前を NAME ヘッダに付加して送信します。ファイルのタイプを送信したい場合は -type オプションにて指定します。指定されたタイプを TYPE ヘッダにて送信します。受信したファイルは指定されたファイル名で保存を行います。送信先のデバイスはこのコマンドの実行よりも前にサーバーとして受信状態にしておく必要があります。

ファイルの送受信(サーバー)

java obex server [option]
    -put [enable/disable]
    -get [enable/disable]
    -name [accept/not-accept]
    -setpath [accept/not-accept]
    -verbose
    -port [port]

サーバーとしてリクエストを受け付けてその処理を行います。PUTGET オペレーションを受け入れるかどうかを -put および -get オプションで指定します。デフォルトでは両オペレーションとも受けれいます。 -port オプションでポートが指定された場合、TCP/IPのそのポートにリクエストが行われるのを待ちます。 -port オプションを指定しなかった場合は赤外線デバイスでリクエストを待ちます。 -name オプションと -setpath オプションはそれぞれの指定を受け入れるか否かを指定します。デフォルトでは NAME ヘッダは受け入れますが、 SETPATH オペレーションは受け入れません。サーバーが受信を開始してからクライアントを実行する必要があります。

全てのモードにおいて、 -verbose オプションを付加すると進行状況を詳細にレポートします。

さらに詳しいことは付属のソースコード obex.java を参照してください。

inbridge

inbrdigeはTCP/IPによるネットワークと赤外線通信のブリッジを行うサンプルアプリケーションです。このinbridgeを使用することにより、NTTドコモが公開している「iαppli Development Kit」を用いて実際の504i/iSシリーズと赤外線通信を行うことが可能になります(最新バージョンではネイティブでOBEXサポートが行われているため、本ソフトウェアを用いずとも実機と赤外線通信することができます。この件について同ソフトのリリースノートには不適切な記述があり実機とは通信ができない旨の記載があるものがありますが、実際には可能となっています)。inbridgeの書式を以下に示します。

赤外線側をサーバーとする場合

java inbridge server [port]

赤外線側(つまり504i/504iS)をOBEXサーバーとしてネットワーク側(つまりiαppli Development Kit)をクライアント側として動作させる場合にこの書式にて実行します。ポート番号を省略した場合は650番(TCP/IP)を使用します。

赤外線側をクライアントとする場合

java inbridge client [address] [port]

ネットワーク側(つまりiαppli Development Kit)をサーバー側、赤外線側(つまり504i/504iS)をサーバー側として動作させる場合にこの書式にて実行します。ネットワーク側のアドレスとポートを指定することができます。この指定を省いた場合はlocalhostの650番(TCP/IP)に接続します。

このアプリケーションは作成してからほとんどテストしていないため正常に動作しない可能性が他のソフトウェアより高くなっていますのでご注意ください。また巨大なデータを中継させようとするとそれだけメモリを消費するのでその点もご注意ください。

アプリケーションの記述方法

OBEXライブラリを使用して実際に通信を行うアプリケーションを行う方法について解説します。

このOBEXライブラリは通信を担当するコネクションとそのコネクションの要求を伝えるソケットから構成されています。この二つを結びつけるのがマネージャー(ObexManagerクラスです。通信をはじめる前にこのマネージャーを経由してコネクションオブジェクトを取得します。

ソケットについて

通信を行うコネクションはOBEXライブラリ側にのみ存在します。これに対してソケットはOBEXライブラリ側にも独自に定義したものをアプリケーションで用意することもできます。そこで、まずソケットとコネクションの関係について解説しておきます。

ソケットはコネクションがOBEXプロトコルに沿って作成したパケットの送受信を行います。OBEXライブラリにはデフォルトで赤外線(IrDA)およびTCP/IPを用いたソケットが付属しています。これ以外のソケットはクライアント側はObexClientSocketインターフェース、サーバー側はObexServerSocketインターフェースを実装することで提供することができます。これらのソケットは自身をObexManagerクラスにregisterSocketメソッドで登録することで使用可能となります。通常、これらの登録はクラスがロードされた際に実行される静的初期化子(クラス内のstatic {}ブロック)で行います。アプリケーションが必要に応じてクラスをClassクラスのforNameメソッドでロードすることで使用可能となります。

ソケットはクライアント用とサーバー用を個別に登録することができます。このため、例えばあるソケットがサーバー用にしか提供されない場合、クライアントコネクションオブジェクトを取得するObexManagerクラスのgetClientメソッドを呼び出すとIllegalArgumentException例外クラスがthrowされます。

以下にデフォルトでOBEXライブラリが提供するソケット名とその対応の一覧を示します。

デフォルトで提供されるソケット一覧
ソケット名対応パラメータ説明
IrDAクライアントおよびサーバーなしIrDAデバイスを通じてクライアントおよびサーバーとしての通信処理を担当するソケットです。ネイティブ処理を伴うため、Windows上でのみ使用可能です。
TCP/IPサーバーjava.net.ServerSocketTCP/IPのサーバー側の通信処理を担当するソケットです。全てJavaで記述しているため、Windowsに限定することなく全てのJava実行環境で実行可能です。Java 2 SDK, Standard Edition, version 1.4からサポートが開始されたIPv6環境でも動作します。
TCP/IPクライアントjava.net.SocketTCP/IPのクライアント側の通信処理を担当するソケットです。全てJavaで記述しているため、Windowsに限定することなく全てのJava実行環境で実行可能です。Java 2 SDK, Standard Edition, version 1.4からサポートが開始されたIPv6環境でも動作します。

クライアントで通信を行う

クライアントの通信はObexManagerクラスのgetClientメソッドからクライアントコネクションオブジェクトを受け取るところから開始します。getClientメソッドは使用するソケットの名前と必要に応じてオブジェクトを渡すことでクライアントコネクションオブジェクトを返します。対応するソケットが存在しないか、パラメータが不正な場合にはObexException例外クラスをthrowします。

赤外線を用いてクライアントコネクションオブジェクトを取得し、PUTオペレーションを実行して接続解除する例を以下に示します(例外処理は省いています)。

クライアント側処理の例
// コネクションオブジェクトの取得
ObexClientConnection occ = ObexManager.getClient("IrDA");

// サーバーへ接続
occ.connect();

// サーバーへPUTオペレーションを送信します。
occ.setBody("クライアント側から送信したBODYです。".getBytes());
occ.setName("text.txt");
occ.setOperation(ObexConnection.PUT);
occ.sendRequest();

// 接続を解除します。
occ.setOperation(ObexConnection.DISCONNECT);
occ.sendRequest();

// 接続を閉じます。
occ.close();

サーバーで通信を行う

サーバー側の処理はクライアント側からの要求にしたがって処理を行う点が異なります。処理の主従はクライアント側が主でサーバー側が従となります。サーバー側のコネクションオブジェクトはObexManagerクラスのgetServerメソッドにソケット名を渡して取得します。対応するソケットが存在しないか、パラメータが不正な場合はObexException例外クラスをthrowします。

TCP/IPを用いてサーバーソケットオブジェクトを取得し、GETオペレーションに対してデータを送信し、接続解除する例を以下に示します(例外処理は省いています)。

サーバー側処理の例
// TCP/IPのソケットを用意してサーバーコネクションオブジェクトを取得します。
ServerSocket srvsock = new ServerSocket(650);
ObexServerConnection osc = ObexManager.getServer("TCP/IP", srvsock);

// クライアントからの接続要求を受け付けます。
osc.accept();

// オペレーションを受け取る変数を宣言します
int nOperation = -1;

// 接続解除を求められるまでループします
while(nOperation != ObexConnection.DISCONNECT)
{
    // リクエストを受信します
    osc.receiveRequest();
    // リクエストされたオペレーションコードを取得します
    nOperation = osc.getOperation();
    
    // オペレーションがGETであれば返信する内容を用意します
    InputStream is = null;
    if(nOperation == ObexConnection.GET) {
      is = new ByteArrayInputStream("GETオペレーションに対するBODYの内容です。".getBytes());
    }
    // リクエストに対するレスポンスを返します。
    osc.sendResponse(ObexConnection.SUCCESS, is);
    if(is != null) is.close();
}

// 接続を閉じます。
osc.close();

ソケットの記述方法

前述のように、OBEXライブラリではOBEXプロトコルの処理全般を行うコネクションと通信経路に関する処理を行うソケットとに分かれています。コネクションはOBEXライブラリそのものであり、OBEXライブラリによって提供されます。これに対してソケットはOBEXライブラリにも内蔵されていますが、その他の実装を独自に提供することができます。ここではソケットを独自に提供する方法について解説します。

ソケットはサーバー側のソケットを規定するObexServerSocketインターフェースあるいはクライアント側のソケットを規定するObexClientSocketインターフェースを実装することで記述します。また、インターフェースの実装とは別に、クラスがロードされた際に実行される静的初期化子(クラス内のstatic {}ブロック)でObexManagerクラスのregisterClientSocketメソッドあるいはregisterServerSocketメソッドを呼び出して自身を登録するように記述します。

サーバー側のソケットとクライアント側のソケットで異なるのは、サーバー側にはaccpetメソッドが、クライアント側にはconnectメソッドが存在する点です。それ以外のメソッドは両者の間で共通です。それぞれのメソッドの内容についてはAPIリファレンスを参照してください。

ソケットにはアプリケーションが使用するための「公開名」とOBEXライブラリがライブラリを認識するための「内部名」が存在します。これらの名前はクライアントとサーバーの双方で別の名前空間で管理されています。このためサーバーとクライアントで同じ名前を使用することができます。

内部名はアプリケーションが不用意にソケットの登録をObexManagerクラスからderegisterClientSocketメソッドあるいはderegisterServerSocketメソッドで削除することがないように用意しました。ソケットを削除する場合は「公開名」と「内部名」の2種類が必要で、両方が一致した場合に限り、削除することができます。

接続に必要な情報はsetParameterメソッドで受け取ります。期待するオブジェクトと異なるオブジェクトを渡された場合やパラメータが不要であるのにも関わらずオブジェクトが渡されなどの場合はIllegalArgumentException例外クラスをthrowします。

以上の指針に沿ってソケットを実装すればOBEXライブラリが標準で対応している以外の機器でもOBEXプロトコルによる通信が行えるようになります。

よくありそうな質問と答え

リソースの確保に失敗するのですが、なぜですか?
赤外線デバイスを占有する何らかのソフトウェアが実行中のためです。例えばWindows2000ではデフォルトでInfrared Monitorというサービスが稼動しています。こういったソフトを停止する必要があります。
Infrared Monitorサービスの止め方を教えてください。
コマンドプロンプトで「net stop irmon」というコマンドを実行することで停止するはずです。ただし、稀に停止しない(永遠に待たされる)ことがあるので、その場合は再起動後に再挑戦してください。
PalmIIIcからファイルを転送するとめちゃくちゃに文字化けしたファイル名で受信します。バグですか?
PalmIIIcのバグだと思います。最近のPalmは所持していないので現在もこのようになるか作者は把握していません。
OBEXとはなんですか?
Object Exchangeの略称であり、そのプロトコルの名前を指します。Webで使用するHTTPのバイナリ版的なプロトコルです。当初赤外線向けに策定されましたが、現在はBluetoothでも採用されています。仕様はINFRARED DATA ASSOCIATIONが策定しています。プロトコルについては同団体が公開している有償の公式仕様書(英語)を参照してください。
使い方がよく分かりません。
手取り足取り教えることはできませんので身近な詳しい方に尋ねるか専門書等をあたってみてください。
バグを見つけたのですがどのように報告すればいいですか?
なるべく具体的な再現方法と問題点をメールにてお知らせください。よろしくお願いします。

配布パッケージの内容

この配布パッケージに含まれるファイルの分類を以下に示します。

赤外線OBEX通信ライブラリ

obexlib.jar
ksjobex.dll

サンプルアプリケーションobex

obex.class
RequestReceiveOutputStream.class
OBEXCommandException.class
obex.java

サンプルアプリケーションinbridge

inbridge.class
inbridge.java

APIリファレンス

docs/allclasses-frame.html
docs/allclasses-noframe.html
docs/constant-values.html
docs/deprecated-list.html
docs/help-doc.html
docs/index-all.html
docs/index.html
docs/overview-tree.html
docs/package-list
docs/personal/
docs/personal/sakaki/
docs/personal/sakaki/io/
docs/personal/sakaki/io/class-use/
docs/personal/sakaki/io/class-use/ObexAuthenticator.html
docs/personal/sakaki/io/class-use/ObexClientConnection.html
docs/personal/sakaki/io/class-use/ObexClientSocket.html
docs/personal/sakaki/io/class-use/ObexConnection.html
docs/personal/sakaki/io/class-use/ObexException.html
docs/personal/sakaki/io/class-use/ObexManager.html
docs/personal/sakaki/io/class-use/ObexServerConnection.html
docs/personal/sakaki/io/class-use/ObexServerSocket.html
docs/personal/sakaki/io/class-use/ObexSocket.html
docs/personal/sakaki/io/ObexAuthenticator.html
docs/personal/sakaki/io/ObexClientConnection.html
docs/personal/sakaki/io/ObexClientSocket.html
docs/personal/sakaki/io/ObexConnection.html
docs/personal/sakaki/io/ObexException.html
docs/personal/sakaki/io/ObexManager.html
docs/personal/sakaki/io/ObexServerConnection.html
docs/personal/sakaki/io/ObexServerSocket.html
docs/personal/sakaki/io/ObexSocket.html
docs/personal/sakaki/io/package-frame.html
docs/personal/sakaki/io/package-summary.html
docs/personal/sakaki/io/package-tree.html
docs/personal/sakaki/io/package-use.html
docs/resources/
docs/resources/inherit.gif
docs/serialized-form.html
docs/stylesheet.css

このreadmeファイル

readme.html

あとがき

予告から5年も過ぎてしまいましたが、機能制限をして使用不可状態に置いていたOBEX認証を動作するように変更しました。またJavaのバージョンもかなり上がったことから、コンパイルおよびドキュメントの生成を行う環境もJava SE 6に引き上げました(開発環境もEclipseに移行しました)。この関係で以前のバージョンでは動いていたけれど、新しいバージョンでは動作しない環境もあるかもしれません。気が付いた点がありましたらメールにてお知らせいただければと思います。

謝辞

初期のバージョンにおいてWindows98で動作確認をしていただいた布留川 英一氏と、テストに使用したPalmIIIcを提供していただいたなかむら(う)氏に感謝いたします。

更新履歴


Copyright(C) 2002-2008 by KEI SAKAKI.
ALL RIGHTS RESERVED.
一部および全体を問わず無断で転載および再配布等を行うことを禁じます。