SSブログ

OS X用GigE Visionカメラドライバ - その9 [OS X用GigE Vision]

昨日はデバイス探索のためにUDPのブロードキャストを流す、というコードを書いてみた。今日は、ではどんなデータをブロードキャストすればいいのかと、カメラはそのときどう答えるのか、ということについて。

10/29追記:コードに間違いがあった。修正。

4.2  デバイス探索のコマンドフレーム

一般のコマンドフレームはまたあとで整理するとして、このときに送り出したデバイス探索のためのコマンドフレームを図-1に示しておく。

1010fig01.png
GVCPのコマンドフレームは少なくとも最初の8バイト(通信分野では8オクテットというのが正しいらしい)はこれと同じ構造をしている。それぞれの詳細はGVCPコマンドを説明するときに一括してまとめる。
これをCの構造体として書くと
#import <CoreFoundation/CoreFoundation.h>

typedef struct _gigeCommandHeader {
    UInt8   keyCode;    //  0x0042
    UInt8   flag;       //  0x8000
    UInt16  command;    //  0x00000002
    UInt16  length;     //  0
    UInt16  req_id;
} gigeCommandHeader;
となる。ちなみにCで書いたときにカメラへ流すためにはそれぞれのフィールドのバイトオーダはネットワークエンディアン(すなわちビッグエンディアン)でないといけないことに注意する。

この0x00000002というコマンドがデバイス探索であるぞ、というしるしである。また先頭の0x0042はGVCPのフレームであるぞ、というキーコードで、デバイス側では先頭バイトの値がこれ以外のフレームはすべて無視される。

ちなみにlengthはこのヘッダをのぞいたバイト数で、デバイス探索コマンドの場合このあとになにもないので0である。コマンドによっては付加情報が必要なので、その付加情報のバイト数を表すことになっている。

最後のreq_idはデバイス探索コマンドの場合0以外ならなんでもいい。この意味はあとで説明する。

4.3  デバイスが反応する

このデバイス探索のフレームがデバイスに届いたとき、デバイスはどうするか、というのを疑似コードを書いて考えてみる。もちろんデバイスのOSがunixであるとは限らないので、こんなコードで書かれているかどうかはわからない。

デバイス側はすでにIPアドレスが決まって、ホストから接続されるのを待っている状態のはずである。

デバイス側のコードはたとえば
    int sock;
    struct sockaddr_in recvAddr;
    struct sockaddr_in sentAddr;
    ssize_t	           len;
    socklen_t          sentLen = sizeof(sentAddr);
    
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    recvAddr.sin_family = AF_INET;
    recvAddr.sin_port = htons(3956);
    recvAddr.sin_addr.s_addr = INADDR_ANY;
    
    bind(sock, (struct sockaddr *)&recvAddr, sizeof(recvAddr));
    len = recvfrom(sock, buf, sizeof(buf), 0
            (struct sockaddr *)&sentAddr, &sentLen);
というようなはずである。つまりsocketを作って、コマンドのポート番号で、アドレスにはINADDR_ANYを指定して、どこからきてもいい、ということにする。

そしてsocketにアドレスをバインドしてrecvfrom()でデータを待つ。

ブロードキャストが到達するとfrecvfrom()から返ってlenが正の数だとなにかがこのポートに来た、ということになる。ようするにたとえばNTPDHCPなんかのUDPを経由するサーバがやってることと基本的には全く同じ(NTPやDHCPは複数の接続に対応できるように、もうすこし複雑にはなってるけど)。

あとは到着したデータの先頭バイトが0x0042であってコマンドがデバイス探索のコマンドであれば、デバイスは応答を返すことになる。

recvfrom()システムコールは送ってきた相手のアドレスがわかるようになっている(上の疑似コードのsentAddrに入ってくる。その値そのものはもともとIPヘッダに含まれている)ので、応答はこのアドレスに返せばいい。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。