指定のSSIDに接続する
現在、DSの「WiFiコネクション設定」に設定したアクセスポイントに自動接続するプログラムのみ作っていて、意識して指定のSSIDをもつWiFiのアクセスポイントに接続することはしていませんでした。
「WiFiコネクション設定」自体は3箇所まで設定できるので、今までは十分だったのですが、ポケットWiFiを買って、これにつなげるプログラムを作っているときに、テストしようと思ったら自宅のAPに自動で繋がってしまうなどの不便さが出てきたので、自動接続ではなく、指定のSSIDに接続するプログラムを作ってみました。*1
APに接続してIPなどを自動取得する
プログラムは簡単で、Wifi_ConnectAP()という関数があるので、これを呼ぶだけで接続できます。ただし、これを呼ぶだけではDHCPからIP等の自動取得はできませんでした。そこで、dswifiライブラリではどうしているかを調べました。
- Wifi_AssocStatus()
dswifiライブラリのwifi接続関連のプログラムはwifi_arm9.cにまとまっています。その中で実際にAPに接続した後、いろいろと設定するところはWifi_AssocStatus()が行っていることがわかりました。Wifi_AssocStatus()を何回も呼び出すことで、wifi_connect_state値を変更して行きつつ接続処理を進めていくフローになっていました。
だから、自動接続の場合も、下記のようにWifi_AssocStatus()をループさせるプログラムになっているのですね。
bool Wifi_InitDefault(bool useFirmwareSettings);内部の処理。
useFirmwareSettingsがtrueのときに自動接続する。if(useFirmwareSettings) { int wifiStatus = ASSOCSTATUS_DISCONNECTED; Wifi_AutoConnect(); // request connect while(wifiStatus != ASSOCSTATUS_ASSOCIATED) { wifiStatus = Wifi_AssocStatus(); // check status if(wifiStatus == ASSOCSTATUS_CANNOTCONNECT) return false; swiWaitForVBlank(); } } }
そこで、Wifi_AssocStatus()において、ステータスがASSOCSTATUS_ACQUIRINGDHCPとなるところのソースを見てみました。
if(wifi_hw) { if(!(wifi_hw->ipaddr)) { sgIP_DHCP_Start(wifi_hw,wifi_hw->dns[0]==0); wifi_connect_state=2; return ASSOCSTATUS_ACQUIRINGDHCP; } }
このソースから、wifi_hwがセットされていて、wifi_hw->ipaddrが0のときにIP取得プログラム(sgIP_DHCP_Start)がスタートするということがわかります。
では、Wifi_ConnectAP()を呼ぶときに、実際のIPアドレスがどうなっているのか調べたところ、初期値なのか?wifi_hw->ipaddrに192.168.1.151がセットされていました。なるほど、これではDHCPが始まりません。
そこで、Wifi_ConnectAP()を呼ぶ前に、Wifi_SetIP( 0, 0, 0, 0, 0 );を実行して本体のIP設定等を全てクリアする処理を追加しました。そうすると、きちんとDHCPサーバから情報を取得するようになりました。
逆に言うと、先にWifi_SetIP()でネットワーク情報をセットしておけば、自動取得しないでくれるようですね。
bool DS_ConnectAP( char* ssid, int wepmode, u8* wepkey )
ということで、DS_ConnectAP()という関数を作りました。
- char* ssid
接続したいAPのSSIDです。
- int wepmode
WEPモードです。dswifiでは、WEPMODE_NONE , WEPMODE_40BIT , WEPMODE_128BITがdefineされています。
- wepkey
WEPキー列です。
これらを引数にして指定SSIDに接続し、IPアドレスなどを自動取得します。成功すればtrueが返ってきます。
//************************************************** // 指定SSIDのアクセスポイントに接続します // ssid: SSID, // wepmode: WEPMODE_NONE/WEPMODE_40BIT/WEPMODE_128BIT // wepkey: WEP KEY // true:無事繋がった。flase:接続できなかった //************************************************** bool DS_ConnectAP( char* ssid, int wepmode, u8* wepkey ) { Wifi_AccessPoint wifiAc; int i, ret; int status = ASSOCSTATUS_DISCONNECTED; strcpy( wifiAc.ssid, ssid ); wifiAc.ssid_len = strlen( ssid ); for( i=0; i<6; i++ ){ wifiAc.bssid[i] = 0; wifiAc.macaddr[i] = 0; } wifiAc.channel = 0; Wifi_SetIP( 0, 0, 0, 0, 0 ); Wifi_ConnectAP( &wifiAc, wepmode, 0, wepkey ); ret = false; //最大10秒待って、結果を返す for( i=0; i<600; i++ ){ if( status==ASSOCSTATUS_ASSOCIATED ){ ret = true; break; } else if( status==ASSOCSTATUS_CANNOTCONNECT ){ ret = false; break; } status = Wifi_AssocStatus(); swiWaitForVBlank(); } return( ret ); }
今日はこの辺で。
本当にやりたいことリスト
(ブログの終わりにやりたいことを書いておきたいと思います)
- 求職活動・・・このブログで興味を持った人一声かけてください。m(_ _)m
- Androidプログラム
- Web系のプログラム
*1:このプログラムはds2dstest.zipに含まれています