ずいぶん間があいてしまったけど「NetBSDでDoCoMo A2502をつかう」の続き。
DoCoMoのA2502は、正しくアタッチするとシリアルポートが3本生成される、ということは前回のエントリーで書いた。最初の一本は通信するためのモデムポートだが、残りの2本は通信以外に利用されている。
3本目のシリアルポートは通信制御や各種情報を取得するために利用されているようなので、少し中身を見ていたが、まとまったのでメモとしてここに書いておくことにする。
3本目のシリアルポートの使い方
D02HWなどと違って、atコマンドを受理したりはしてくれない。バイナリを送るとバイナリで返事をくれる、という仕様になっているようだ。(コマンドを全部解析したわけではないが、とりあえずアンテナレベルの取得くらいははできる。)
処理シーケンス
- シリアルポートをオープンする
- {0xcf, 0x18, 0x00, 0xc0, 0xdd, 0x7e}を書き込む。
- 12バイトの返事がくるので読む(解析していない)
- {0xcf, 0x00, 0x00, 0x91, 0x86, 0x7e}を書き込む
- 14バイトの返事がくるので読む(解析していない)
- {0xcf, 0x07, 0x00, 0x99, 0xcb, 0x7e}を送ると、自分の電話番号などが含まれた51バイトの情報が返ってくる。(電話番号は5から16バイトの間)
- {0xcf, 0x01, 0x00, 0x49, 0x9f, 0x7e}を送ると、シグナルレベルや、つながっているネットワークのIDが含まれた58バイトの情報が返ってくる(シグナルレベルは7バイト目、ネットワークIDは26から40バイト目)
rubyを用いたサンプルコード
というわけで、アンテナレベルと繋がっているネットワークの名前を出力するサンプルコードを載せておく。今回はrubyで書いてみた。シリアルポートのサポートライブラリにruby-serialを使っているので動かす場合にはインストールしておくこと。
require "serialport"
# open control serial port 38400/N81
sp = SerialPort.new("/dev/ttyU2", 38400, 8, 1, SerialPort::NONE)
sp.flow_control= SerialPort::NONE
cmd0 = [0xcf, 0x18, 0x00, 0xc0, 0xdd, 0x7e].pack('C*')
cmd1 = [0xcf, 0x00, 0x00, 0x91, 0x86, 0x7e].pack('C*')
telno = [0xcf, 0x07, 0x00, 0x99, 0xcb, 0x7e].pack('C*')
antcmd = [0xcf, 0x01, 0x00, 0x49, 0x9f, 0x7e].pack('C*')
cnt = 0
sp.write(cmd0)
buf = sp.read(12)
sp.write(cmd1)
buf = sp.read(14)
sp.write(telno)
buf = sp.read(51)
data = buf.unpack('C*')
telno = data[5..16].map!{|c| c.chr}.join
print "tel no:" , telno, "\n"
while (cnt < 20)
sp.write(antcmd)
buf = sp.read(58)
data = buf.unpack('C*')
network = data[26..40].map!{|c| c.chr }.join
print "signal level:" , data[17], " [network:" , network , "]\n"
cnt+=1
sleep 1
end
出力は
$ ruby a2502ant.rb
tel no:080XXXXXXX
signal level:20 [network:]
signal level:20 [network:]
signal level:20 [network:]
signal level:20 [network:]
signal level:20 [network:]
signal level:18 [network:]
signal level:18 [network:NTT DoCoMo]
signal level:19 [network:NTT DoCoMo]
[省略]
のようになる。アプリケーションを作る場合などにそれなりに使えるかな。
0 件のコメント:
コメントを投稿