YAPC::Asia 2007 Tokyo で大人気だった USB::MissileLauncher をマルチに制御するパッチを作りましたので公開します。
Multi-USB::MissileLauncher for Win32 binary package
http://namazu.org/~takesako/pub/usblauncher-20070501.zip
■ ctlmissileコマンド使用法
Usage: ctlmissile [ up | down | left | right | fire | stop ] [ 3000]
オリジナルからの変更点
http://www.earth.li/~noodles/files/usblauncher-0.0.3.tar.gz からの変更点
* ctlmissile.c.patch
- コンパイルオプション -DLINUX -DWIN32 の追加
(Linux以外のWindows、Mac OS X の環境でも動作するように)
- msec秒でコマンドを発行するコマンドライン引数 [ 3000 ] を追加
- 複数のUSBミサイルランチャーの接続に対応
同時制御と逐次制御が可能
■ インストール方法
Windows の場合
事前にLibUsb-Win32からダウンロードできるlibusb-win32-filter-bin-0.1.12.1.exeをインストール
$ gcc -DWIN32 ctlmissile.c -o ctlmissile -lusb
Linux の場合
ディストリビューション付属のlibusbパッケージをインストール
$ gcc -DLINUX ctlmissile.c -o ctlmissile -lusb
Mac OS X の場合
libusbをインストール
$ gcc ctlmissile.c -o ctlmissile -lusb
■ 応用
POE::Component::Server::TCPを使って、USBミサイルランチャーを制御するTCPデーモンを1時間で書く。
missile_server.pl
#!/usr/bin/perl
use POE qw(Component::Server::TCP);
use strict;
sub main {
my $bind_port = $ARGV[0] || 6969;
my $kernel = POE::Component::Server::TCP->new(
Port => $bind_port,
Error => \&error_handler,
Concurrency => -1,
ClientInput => \&handle_client_input,
ClientConnected => \&handle_client_connect,
ClientDisconnected => \&handle_client_disconnect,
ClientError => \&handle_client_error,
ClientFlushed => \&handle_client_flush,
ClientShutdownOnError => 0,
);
POE::Kernel->run();
}
sub accept_handler {
my ($socket, $remote_address, $remote_port) = @_[ARG0, ARG1, ARG2];
}
sub error_handler {
my ($syscall_name, $error_number, $error_string) = @_[ARG0, ARG1, ARG2];
}
sub exe {
my ($cmd) = @_;
$cmd =~ s/[^\s\d\w]//g;
system split(/\s+/, $cmd);
}
sub handle_client_input {
my $heap = $_[HEAP];
my $kernel = $_[KERNEL];
my $input_record = $_[ARG0];
my $msg = "yes sir, $input_record";
if ($input_record =~ m/(shutdown|quit)/i) {
$kernel->yield("shutdown");
$msg = "connection closed...";
} elsif ($input_record =~ m/help/i) {
$msg = "Ugage: [ up | down | left | right | fire | stop ] [ 3000 ]";
} elsif ($input_record =~ m/^\s*$/ims) {
$msg = "help";
} else {
exe("ctlmissile $input_record");
}
$heap->{client}->put($msg);
}
sub handle_client_error {
my ($syscall_name, $error_number, $error_string) = @_[ARG0, ARG1, ARG2];
}
sub handle_client_connect {
my $heap = $_[HEAP];
$heap->{client}->put("connected on USB-Missile-Launcher 200 OK");
}
sub handle_client_disconnect {}
sub handle_client_flush {}
main();
1;
POEのプログラミングは初めてでしたが、perldoc POE::Component::Server::TCP 見ながら簡単に書けました。
■参考URL
YappoLogs: ミサイルは国境を越える
http://blog.yappo.jp/yappo/archives/000504.html
Google Maps: ミサイルが本当に国境を越えてる???
http://maps.google.com/maps?q=38.22657,-112.299&z=18&t=k
Tilting Google Maps and MissileLauncher - SlideShare (miyagawa-san at osdc.tw)
http://www.slideshare.net/miyagawa/tilting-google-maps-and-missilelauncher/
throw new CybozuLabsException() - libusbを使うPHP Extensionを作りました
http://labs.cybozu.co.jp/blog/tsuruoka/anubis/blog_show/43
TokuLog 改め Perl を極めて結婚するブログ - missile on ruby.
http://d.hatena.ne.jp/tokuhirom/20070407/1175935832
西尾泰和のブログ @ Cybozu Labs: PythonワンライナーでUSBミサイルランチャーを制御
http://labs.cybozu.co.jp/blog/nishio/2007/04/pythonusb.html
*BSDでのUSBデバイスドライバーの実装
http://www.ofug.net/~yamajun/presentation/2003/usb.html
ToDo
ctlmissile.cで複数のミサイルランチャーを制御する拡張コマンドを追加したので
(ひ)メモ - Assurer::Plugin::Notify::Missileの概要設計の実装が待たれるところです。