Microbit ラズパイ Bluetooth〜マイクロビットとラズパイ間をSDPで通信する〜

今回は、Microbitとラズパイの間をBluetooth経由で通信するためのサーバーを作成し始めようと思います。
参考にするページは本家Oracleのページです

元々のやりたいこと

一応この実装の目的は、Microbitからのbluetooth経由メッセージをラズパイで受信して、Midiメッセージを音源モジュールに送信、音を鳴らすというのが目的です。下はイメージになります。

SDPで通信

SDP(Sockets Direct Protocol)はMicrobitとラズパイの通信で使用できるという情報を得て、現在に至りますが、早い話が、Bluetoothでの通信時にこのSDPが使用できるということです。このテクノロジーを使用するためにサポートされて(JDKに入って)いるクラスは下に記載しました。(参考サイト参照)

  • java.net package
    • Socket
    • ServerSocket
  • java.nio.channels package:
    • SocketChannel
    • ServerSocketChannel
    • AsynchronousSocketChannel
    • AsynchronousServerSocketChannel

必要な作業

  1. SDP構成ファイルの作成
  2. SDPプロトコルの有効化
  3. SDPのデバッグ

こんな感じの作業が必要になると思いますが、如何せんやってみないことには始まらないので。。。

SDPサーバーを作る

SDP構成ファイルの作成このページを読んでみると、構成ファイル(設定ファイル)を作る必要がある、と記載しているのでその通りにやってみます。。。
しかし、記載ルールが書いてあるだけなのでよくわからない状態です。
わからないので調べます。そして、ちょうど良いのがありました。設定ファイルのテンプレートのようなものらしいです。早速失敬して。。。
ご丁寧に、全部コメントアウトされています。必要な部分を修正、コメントを外して使用します。

設定ファイル(Conf File)

#
# Configuration file to enable InfiniBand Sockets Direct Protocol.
#
# Each line that does not start with a comment (#) is a rule to indicate when
# the SDP transport protocol should be used. The format of a rule is as follows:
#   ("bind"|"connect") 1*LWSP-char (hostname|ipaddress["/"prefix]) 1*LWSP-char ("*"|port)["-"("*"|port)]
#
# A "bind" rule indicates that the SDP protocol transport should be used when
# a TCP socket binds to an address/port that matches the rule. A "connect" rule
# indicates that the SDP protocol transport should be used when an unbound
# TCP socket attempts to connect to an address/port that matches the rule.
# Addresses may be specified as hostnames or literal Internet Protocol (IP)
# addresses. When a literal IP address is used then a prefix length may be used
# to indicate the number of bits for matching (useful when a block of addresses
# or subnet is allocated to the InfiniBand fabric). 

# Use SDP for all sockets that bind to specific local addresses
#bind    192.168.4.1    *
#bind    fe80::21b:24ff:fe3d:7896    *

# Use SDP for all sockets that bind to the wildcard address in a port range
#bind    0.0.0.0    5000-5999
#bind    ::0        5000-5999

# Use SDP when connecting to all application services on 192.168.1.*
#connect 192.168.1.0/24       1024-*

# Use SDP when connecting to the http server or MySQL database on hpccluster.
#connect hpccluster.foo.com   80
#connect hpccluster.foo.com   3306

Socketの実装

以前作成したものですが、これに設定ファイルを適用すればいけるみたいです。下のものはSocketサーバーを起動するコードです。
クライアントから送信されたメッセージ(テキストなど)をそのまま返す処理になっています。

public void startServer() {
    try {
        System.out.println("*** SocketServer start " + server.isBound() + "***");
        Socket recieve = server.accept();
        System.out.println("*** Server Get Request start***");
        // 受信データの読み込み
        StringBuilder responseTxt = new StringBuilder("");
        // 受信状態
        System.out.println("クライアント: " + recieve.getRemoteSocketAddress());
        System.out.println("接続: " + recieve.isConnected());
        System.out.println("入力ストリームが閉じている: " + recieve.isInputShutdown());

        // 受信したリクエスト
        InputStream in = recieve.getInputStream();
        // 返却するレスポンス
        OutputStream writer = recieve.getOutputStream();
        System.out.print("Server recieve is ...");
        int c = 0;
        // CRとCRLFの場合で入力が終了している時がある
        while((c = in.read()) != -1) {
            char ch = (char)c;
            responseTxt.append(ch);
            // 空の場合
            if (c == 10 || c == 13) {
                break;
            }
        }
        System.out.println(responseTxt.toString());
        System.out.println("*** Server Send Response start***");
        // レスポンス送信
        writer.write((responseTxt.toString() + System.getProperty("file.separator")).getBytes());
        writer.flush();
        in.close();
        writer.close();
        System.out.println("*** SocketServer end ***");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 開いたストリームを閉じる
        try {
            closeServer();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
一度書けばどこでも動くの精神

ということです(笑)
あとは動かしてみてうまくいくかどうか?を確認します。
そして、これをベースにして「〜を受信したときに〜する」というような処理を実装していきます。
ソースはGithubにコミットしてありますので、よかったら全体のソースも見てみてください、

でわでわ。。。