マイコン工作実験日記

Microcontroller を用いての工作、実験記録

ひかり電話からの着呼 -- その2

2008-12-31 19:57:32 | VoIP


ひかり電話からのSIP着呼処理とナンバーディスプレイ処理を組み合わせて動作できるようになりました。それなりにキリのいいところまで作業できて嬉しいです。さぁ、気持ち良く新年を迎えましょうか。

この一年は、W-SIMを中心に実験工作を進めてきましたが、来年は何か新しいテーマも見つけたいものです。AT91SAM7をメインに使っていますが、来年はLPC23xx/24xxとかAT91SAM9にも手を出してみようかとも考えています。ATMELとNXPからもいよいよCortex M3のチップが出てくるでしょうから、それらに手を出すのもいいかもしれませんね。

それでは、来年もよろしくお付き合いをお願いします。

ひかり電話からの着呼

2008-12-24 23:21:30 | VoIP
ナンバーディスプレイの試験がひと段落ついたので、SIP-TAのSIP部分作業を再開して、着呼関連のコードを追加しています。どうにか着呼に応答して通話できるところまではきましたが、まだ処理が間違っているという状況です。こんどの週末にはなんとか修正できるでしょう。

着呼処理では、ひかり電話ルータ(RT-200KI)からのINVITEが拾えずにしばらく悩んでいました。原因はSIPで使うUDPのポート番号が5060になっていなかっただけのことでした。ひかり電話では、登録(REGISTER)や発呼の場合にはポート番号は5060である必要はないのに、着信の際のINVITEは必ず5060に向けて送ってくるという仕様になっています。そのため、登録も発呼もできるのに、着信が全く受けられないという症状になっていたのです。この問題、以前にもX-Liteでひかり電話を使った時にも経験していたのに、すっかり忘れていました。


ひかり電話から発呼できるようになった

2008-12-09 00:19:27 | VoIP
SIP TAのSIPスタックの作業を少し進めた結果、発呼ができるようになりました。時たま音声パケットを拾い損ねるか、SLICに渡し損ねるかしているようで、音がひずんでしまいます。ひととおり発着信処理が動いてから、見直した方が良さそうです。

ひかり電話のルータには、複数の電話機端末を接続でき、内線番号を割り当てられます。内線間での通話ができるので、試験のために(通話料金の発生する)外線を使わなくてもすむのがとっても助かります。

ひかり電話に登録できた

2008-11-15 15:59:32 | VoIP
いちおうひかり電話のルータに登録できるようになりました。ひかり電話のルータは、NTTの網側からみれば それ自体が端末のように見えるはずですが、宅内のSIP端末を収容するサーバとしても機能します。NTTのページによれば 今では数種の対応ルータがあるようですが、ウチはOKIのRT-200KIを使っています。RV-230SEというのもあるんですね。知りませんでした。これは住友電工でしょうか?

RT-200KI側の設定は、次のようにしてあります。ウチではカミさんが仕事に使うFAXと、わたしが実験に使うための番号を追加しているので、合計3つの電話番号を持っています。そこで3つ目の番号をSIP TAに割り当てることにします。IP端末としては5台登録が可能なので、5番目として登録しておきます。



ちょっとややこしいのは、ルータ内で端末を区別するのに使用されている「内線番号」はSIPプロトコル的には "user name"と呼ばれるものであるということでしょうか。ルータ側で設定している「ユーザ名」はダイジェスト認証の際に必要な認証用のusername に相当します。そのため、X-LiteをRT-200KIに登録する場合のアカウント設定は次のようになります。



SIP TA側でも同じ要領でパラメータの設定をするのですが、今はhard codedしています。

現時点では、SIP TAからの登録操作は手動です。モニタから sip registerと打つと、登録をおこなうようにしています。登録が受け付けられると、RT-200KIの管理画面からも次のように状態を確認できます。



まだ登録の更新機能が入っていないので、登録の有効期間(3600秒にしている)を過ぎると登録がはずれてしまいます。発呼ができるようになったら、この部分もちゃんと実装しなければ。

SIP TAソフトを書き始めた

2008-11-12 23:46:02 | VoIP
SLIC評価ボードの基本的動作は確認できたので、SIP TA基板の方のソフト開発作業も開始しました。

まずは、いつものようにTOPPERSとTINETを動かすことから始めました。MMnetSAM7Xのハードウェア構成は基本的にはMake Controllerと同じ AT91SAM7X256とDM8161ですので、VoIP GW用のコードをベースにして作業開始です。Kernel部分で必要な修正は、Make Controllerではログ用にUART0を使ってたのを、今度はDEBUGシリアルが使えるので、これを使うように修正する程度の作業です。

VoIP GWで用意したDHCPまではあっさりと動いたので、SIPスタックの準備にも着手したところです。SIP GWのコードの使えるところは使うのですが、UACとUASの立場が逆になります。また、SIP GWでは処理を簡単化するために認証は省いてしまいましたが、NTTの光電話ルータ(我が家の場合にはOKI製のRT-200KI)を使って登録や発呼する際には認証が必要となるので、この部分も実装しなければなりません。

まずは登録できるところまで、週末までに作業するつもりです。

SIP TA用 親基板

2008-11-03 23:02:27 | VoIP
実物を見て、SLIC評価ボードの子基板は素直にAT91SAM7X256とインタフェースできそうだという感触を強くしたので、SIP端末はアナログ電話を収容するTAとして実現することに決めました。そこで、さっそくこの連休を利用して、早速TA用の親基板を用意しました。いつもの秋月基板がサイズ的にもちょうどよろしいようです。

SLIC基板上には、4つの連結フレームがあるので、これを受けるピンフレームを配置してあります。連結フレームは秋月のものよりも、ずいぶんと足が長くなっています。実際に子基板を載せてみたかったのですが、評価ボードの親基板にかなりガッシリとピンが刺さっており、なかなか抜けてくれません。あまり力を入れると基板が割れるんじゃないかと心配になったので、しばらくは評価ボードは評価ボードとして使っていくことにします。PC上での動作確認がひととおりできたら、思い切って子基板を載せ換えようと思います。



とりあえず電源、JTAG, USBコネクタだけを配線してあります。SLICとして使用している Si3215M自体は 3.3V単一電源で動作するのですが、電話回線との間のハイブリット回路で5Vも使用するようになっていますので、5Vのスイッチングレギュレータを使うことにします。MMnetSAM7Xは3.3V単一電源ですが、基板上にはレギュレータは載っていませんので、2.1φDCジャックの裏側に 3.3V 500mAレギュレータを載せてあります。

現時点での心づもりとしては、この親基板にSLIC子基板を載せただけのハード構成で、SIP TAとしての基本機能を提供するつもりです。その後でLCDを付加するつもりでいます。このTAと電話機を並べて使うことにすれば、電話機側にナンバーディスプレイ機能なんかなくても、LCDで発信者番号確認できます。実験用電話機は安物で済みますし、SIP TA側ではナンバーディスプレイ機能をサポートするために必要な手順やFSK信号生成のソフト開発をはしょることができます。

無事にJTAGでの書き込みと、USB CDCの動作確認まではできたので、MMnetSAM7X単独で使う準備が整いました。しばらくはこの状態でSIP関連のコードの開発を進めていこうかと思います。

天気予報を文字情報で表示する

2008-10-26 19:57:10 | VoIP
前回はDTMFを使ってLCDに表示する情報を切り換えてみましたが、表示する情報はマイコンが持っている情報が主でした。日付/時刻についてはSNTPを使って取得したものを元にしていましたが、このようにネットワークから取得した情報を表示するデバイスとしてLCDを使い、情報の選択に電話番号やDTMFを使うことができます。今回は、この考え方をちょこっと発展させて、天気予報と地震情報をインターネットから取得して表示するデモを作成してみました。



まず、前回と同様にW-SIMへの発呼を伴わない特別な電話番号を用意します。前回は900番を使いましたので、900番代すべての番号はすべてVoIP GWで終端することにして、イベント通知をサーバに対して送出することとしました。実際に使用している番号は901と902のふたつです。

ダイアル番号サービス内容
901天気予報
902地震情報


それぞれの番号に接続すると簡単なメニューが表示されます。DTMFを入力するとメニューに応じて、情報が表示/変化します。天気予報の場合では "0" で今日の天気、"1" で明日、"2" で明後日の予報が表示されます。地震情報では、最新のものから番号順に従って表示されます。

情報源はlivedoorのRSSフィードです。RSSを直接読んできて、XMLを解釈するのはメモリ的に無理なので、発信者名の表示の時と同じように、サーバ側にいったん要求を出して、その応答として画面イメージをもらっています。そのため、SIP GW側の処理は発信者名の表示の場合と大差ありません。シーケンスは次のようになります。



サーバ側には、着信番号とイベント種別が渡されますので、着信番号によって提供するサービスを選択し、RSSフィードの取得と解析を行います。そして、結果の文字列をビットマップに変換してVoIP GWに応答として返します。VoIP GWは単に受け取ったビットマップをそのまま表示しているだけです。実際のサービスを提供しているのはLinux サーバであり、901とか902という番号もVoIP GWでは区別しておらず、901~999の番号であればVoIP GWのふるまいは全く同じです。たとえば、910がダイアルされた場合には、サーバ側に通知されるCALLEDの番号が910に変化するだけです。この場合、サーバ側では対応するサービスが用意されていないので、何の応答もなく、結果としてLCD画面は変化しないこととなります。



DTMFでLCD表示内容を変化させる

2008-10-12 16:17:27 | VoIP
W-SIMを使って発着信する機能を実装するのは、実際に電話がつながるので楽しいことは楽しいのですが、通信料金が発生してしまうのが痛いところです。端末をもう一台契約すれば通話料はタダにできますが、基本料金はかかってしまいます。そこで、SIPは使うけれども、W-SIMは使わないで遊んでみることにしました。X-Liteは、わたしの持っているYealinkのUSB電話機をサポートしているようなので、今回はこの電話機から操作をおこなっています。



以前、DTMFの検出実験をしましたが、その機能をチョコット強化して、DTMFを使ってLCDに表示するデータを変化させるようにしてみました。X-Liteからは、普通にSIPを使って発信するのですが、特別な番号(900)がダイアルされた場合には、VoIP GWが呼を終端してしまい、W-SIMへは中継しないようにします。そして、X-LiteからのDTMF信号によって、LCDに表示される情報を変化させるようにしてみました。実際に表示される情報は次のとおりです。

  • 自局のIPアドレスとDNSサーバアドレス(DTMF 0)
  • 日付と時刻 (DTMF 1)
  • 温度と明るさ(DTMF 2)




DTMFを検出すると、表示項目が切り替わります。日付時刻については、DTMF 1を検出した時点でSNTPを使って時刻を取得し、その後はSAM7のクロックでカウントしています。USB電話機側にも日付/時刻表示がありますが、こちらはPCの時計を使って表示しています。PCの設定時刻がずれているので、VoIP GWの時刻表示とズレが生じでしまいました。

温度と明るさはこの記事で書いたセンサーの値を表示しています。温度については摂氏での表示ですが、明るさはタイマー値をそのまま表示しているだけであり、ルクスへの変換はおこなっていません。温度センサLM60はAT91SAM7X256のADへ直結しているのですが、ADが10bitしかないこともあり、値がバタついています。OPアンプで2~3倍にしてやった方が良かったようです。

今回はDTMFでLCDの表示内容を変化させてみましたが、マイコン側にSSRとかつけてやれば、DTMFでコンセントの電源制御とかもできますね。ブラウザ経由で制御するよりも、電話機で制御できればリモコン並みに手軽に使えるんじゃないかとも思ったりしますが、X-Liteのようなソフトフォンに頼っていたのではPCが必要になってしまいます。ここは、手軽に使えるワイヤレスのSIP端末とか欲しいような気もしてきました。

発信者名の表示

2008-10-05 23:16:31 | VoIP


久し振りにVoIP GWネタです。前回は通話時に音声波形を表示するようにしてみましたが、今回は着信時の機能です。着信時には発信者の電話番号を表示しますが、携帯電話のように電話帳機能があれば、漢字で表示することができます。これまでの自作ジャケットには電話帳機能がありませんでしたので、発信者名の表示はできませんでした。それに漢字フォントをジャケット側に準備するのも面倒です。

今回はEthernetがあるので、この通信機能を使って、サーバ側に電話番号から名前への変換機能を用意することで、発信者名の表示を可能とすることにしました。仕掛けはいたって単純で、下図に示したようにサーバ側に発信者番号情報を渡すと、サーバが発信者名への変換をおこないその漢字表記のビットマップを返すというものです。ビットマップの生成にはいつものようにIPA GUIフォントを使っています。


サーバ側には発信者番号だけでなく、イベントの種別も渡しています。これは、今後、着信以外のイベントを渡して処理することを想定しているためです。プロトコルとしては、UDPで簡易的なもので実験しています。本来であれば、TCPでHTTPとか使って、データの送受もXML形式を使うとかすればWebアプリ的になるのですが、TCP載せるとRAM容量がキツクなってきそうな状況なので、パスすることに。サーバからの応答は、縦40ドット分の画像イメージということに決めつけてしまい、生データを返すだけにしています。そのため、受信処理ではLCDのフレームバッファに応答を読み込むだけで済ましています。そうすると、定期的な画面更新処理が走った時点でLCD画面に表示が現れるというわけです。

シーケンス図に示したように、発信者名が表示される前に短時間ですが、発信者番号が表示されている期間もあります。動画をコマ送りすれば、わかるかもしれません。ただし番号は一部Xでつぶしてあります。また、今回の動画ならびに写真では青色LEDのバックライトを点灯させています。

サーバ側処理も極めて単純化して実験しています。ビットマップ生成は以前 フォントデータ生成に使っていたものをNokia 5110用の生データを出力するように変更したものをひとつのコマンドとして用意しておき、それをPerlで書いたサーバから呼び出して使っています。電話帳データは、いまのところPerlの連想配列としてサーバコードに埋め込んであるだけです。



発信者番号が非通知の場合にはID=には何も番号が載らないので、この場合にはanonymousという名前にVoIP GW上で変換しています。これをサーバ側で漢字表記に変換する際に非通知という文字列に変換することにしました。プロトコル自体はUDPベースで、サーバからの返答内容をビットマップととして、そのままLCDに送っているだけの処理です。

フォントはスケーラブルですので、表示する文字数に応じて適宜フォントのサイズを変更してビットマップイメージを作成しています。これもサーバ側の機能ですので、マイコン側では何にもせずに単に表示しているだけなのですけど。


RFC4733でDTMFを拾ってみる

2008-09-14 11:19:07 | VoIP
W-SIMをつなげて、発信だけでなく着信も動作するようになってきました。かなりいい加減なSIPスタックで、限定的な状態遷移しかサポートしていないし、エラー処理もロクにしていないので、ときどきおかしくなることがあるのですが、そこそこ遊べるようになってきました。次のネタとしてDTMF音を検出して遊んでみることにします。

世の中には、テレフォンバンキングのように音声ガイダンスにDTMF音で応答することで、メニュー選択ができるサービスがたくさんあります。このようにDTMF音を判別して動作する簡易的なメニューをマイコン上に用意してやれば、X-Lite側からのDTMF入力に応じてマイコンにつながるI/Oを制御したりすることも可能でしょう。音声ガイダンスを用意するのはちょっと大変だし、制御するI/Oを追加製作するのも面倒なので、今あるLCD表示だけを使ってできることを考えようと思います。

こんな構想の第一歩としてDTMF音を検出してみることから始めました。まず最初に通話状態にするのですが、実際にPHS網に電話する必要もないので、発呼処理の開発途中と同じようにマイコン上で呼を終端してダミーのRTPを流すことにします。実際にPHS網へ発呼する動作とマイコン上で終端する場合の区別は電話番号でおこなうことにし、900番台の番号がダイアルされた場合には、マイコン上で終端することとします。

SIPを使う場合にはDTMF信号を送る方式にはいつくかの種類があるようです。
  1. イン・バンドでの送信 DTMF音を音声信号として送る。
  2. RFC4733(RFC2833)を使って送信 u-Law音声とは別のRTPペイロードとして、DTMF信号を送信
  3. SIP INFOを使って送信 SIPのINFOメソッドを使って送信する
X-Liteの説明書によると、X-Liteは上記のすべての方式をサポートしているようですが、設定画面にはこれに係る設定は何もありません。どうやら、相手先のふるまいによって、どの方式を使うかを判断して動作するようです。イン・バンド方式では、音声信号のRTPの中からDTMF成分を検出する作業が必要なのでパス。INFO方式のためにはもう少しSIPスタックをまっとうにした方が良いように思えるので、RTP部分で処理できるRFC4733で行くことにしました。

発呼時にX-Liteが出すINVITEのSDPを調べてみると、
<quote>
m=audio 48684 RTP/AVP 0 101
a=fmtp:101 0-15
a=rtpmap:101 telephone-event/8000
</quote>
というようにRTPのペイロード・タイプとして101をサポートしていることを示しています。いままでは、X-LiteからのINVITEに対してVoIP GWからの応答に含まれるSDPでは
<quote>
m=audio 20002 RTP/AVP 0
a=rtpmap:0 PCMU/8000
</quote>
を返していましたので、DTMFはインバンドで送信されていました。応答SDPを
<quote>
m=audio 20002 RTP/AVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
</quote>
に変更してやったところ、次に示すようにRTP EVENTとしてDTMF信号が出力されるようになりました。



X-Lite上のDTMFボタンを押し続けている間、何度かに分けてRTP EVENTが出力されます。そして、ボタンを離すとendを示すイベントが同じ内容で3回出力されるようです。普通のボタンと同じように、ボタンが押されたことと離されたことの区別もできますから、VoIP GWには何のボタンも付けなくても、電話機のDTMFボタンを代わりに使って操作することができそうですね。