diff --git a/build/libraries_sysmenu/wds/ARM9/src/WDS.c b/build/libraries_sysmenu/wds/ARM9/src/WDS.c index 424de9e6..2a18c083 100644 --- a/build/libraries_sysmenu/wds/ARM9/src/WDS.c +++ b/build/libraries_sysmenu/wds/ARM9/src/WDS.c @@ -27,6 +27,9 @@ ***********************************************************************/ #include #include +#ifdef WDS_WITHDWC +#include +#endif //----------------------------------------------------- // Macros @@ -60,19 +63,18 @@ enum */ typedef struct WDSWork { - u8 wmwork[ WM_SYSTEM_BUF_SIZE ]; ///< WMライブラリ用バッファ - - u8 scanbuf[ WDS_SCAN_BUF_SIZE ] ATTRIBUTE_ALIGN(32); ///< スキャンバッファ - WMScanExParam scanparam; ///< スキャンパラメータ - WDSCallbackFunc scancb; ///< スキャン用コールバック - WDSApInfo apinfo[ WDS_APINFO_MAX ]; ///< スキャン出来たAP情報 - u16 linklevel[ WDS_APINFO_MAX ]; ///< 電波強度 - u16 tgid[ WDS_APINFO_MAX ]; ///< 複数のビーコンを受け取った際に識別用に使うTGID - s32 apnum; ///< スキャン出来たAP情報数 - u32 status; ///< ステータス - - MATHCRC32Context crcContext; - MATHCRC32Table crcTable; + u8 wmwork[ WM_SYSTEM_BUF_SIZE ]; ///< WMライブラリ用バッファ + u8 scanbuf[ WDS_SCAN_BUF_SIZE ] ATTRIBUTE_ALIGN(32); ///< スキャンバッファ + WMScanExParam scanparam; ///< スキャンパラメータ + WDSCallbackFunc scancb; ///< スキャン用コールバック + WDSApInfo apinfo[ WDS_APINFO_MAX ]; ///< スキャン出来たAP情報 + u16 rssi[ WDS_APINFO_MAX ]; ///< 電波強度 + u16 tgid[ WDS_APINFO_MAX ]; ///< 複数のビーコンを受け取った際に識別用に使うTGID + s32 apnum; ///< スキャン出来たAP情報数 + s32 apindex; ///< スキャン出来たAPを配列内のどこに書き込むかのインデックス + u32 status; ///< ステータス + MATHCRC16Context crcContext; ///< CRC計算用コンテキスト + MATHCRC16Table crcTable; ///< CRC計算用テーブル } WDSWork; //----------------------------------------------------- @@ -80,6 +82,22 @@ typedef struct WDSWork //----------------------------------------------------- static WDSWork *gWdsWork = NULL; +//-------------------------------------------------------------------------------- +/** WMBssDesc内のrssiのアッテネータ使用フラグを解釈し、単純に大小比較できる値に変換します + @param <1> アッテネータ使用フラグを含んだRSSI + @return 正規化されたRSSI + @note + WMライブラリから移植。 +*///------------------------------------------------------------------------------ +static u8 WDSGetRssi8(u8 rssi) +{ + if (rssi & 0x0002) + { + return (u8)(rssi >> 2); + } + return (u8)((rssi >> 2) + 25); +} + //-------------------------------------------------------------------------------- /** UTF8 → UCS2 へ変換します @param <1> UTF8 文字 @@ -145,6 +163,9 @@ static void WDSScanCallback( void *arg ) u8 rc4key[ 8 ]; BOOL duplicated; const u32 magic = 'WDS!'; + u8 *pCrcData; + u16 crc; + u32 crcLength; // ビーコンの重複チェック duplicated = FALSE; @@ -163,16 +184,32 @@ static void WDSScanCallback( void *arg ) OS_TPrintf( "Found AP GGID : %08x TGID : %04x\n", pParam->bssDesc[i]->gameInfo.ggid, pParam->bssDesc[i]->gameInfo.tgid ); // ビーコン内容をコピーし、暗号化解除 - MI_CpuCopy8( pParam->bssDesc[i]->gameInfo.userGameInfo, &gWdsWork->apinfo[gWdsWork->apnum], sizeof(WDSApInfo) ); + MI_CpuCopy8( pParam->bssDesc[i]->gameInfo.userGameInfo, &gWdsWork->apinfo[gWdsWork->apindex], sizeof(WDSApInfo) ); MI_CpuCopy8( &magic, &rc4key[0], 4 ); MI_CpuCopy8( &pParam->bssDesc[i]->bssid[2], &rc4key[4], 4 ); CRYPTO_RC4FastInit( &rc4context, rc4key, 8 ); - CRYPTO_RC4FastEncrypt( &rc4context, &gWdsWork->apinfo[gWdsWork->apnum], sizeof(WDSApInfo), &gWdsWork->apinfo[gWdsWork->apnum] ); + CRYPTO_RC4FastEncrypt( &rc4context, &gWdsWork->apinfo[gWdsWork->apindex], sizeof(WDSApInfo), &gWdsWork->apinfo[gWdsWork->apindex] ); + + // CRC 判定 + pCrcData = (u8*)&gWdsWork->apinfo[gWdsWork->apindex]; + crcLength = sizeof(WDSApInfo) - sizeof(u16); + MATH_CRC16Update( &gWdsWork->crcTable, &gWdsWork->crcContext, pCrcData, crcLength ); + crc = MATH_CalcCRC16( &gWdsWork->crcTable, pCrcData, crcLength ); + + // 旧バージョンの親機はCRC部分に0x0000を入れているためそれだけは受け入れる + if( crc != gWdsWork->apinfo[gWdsWork->apindex].crc && gWdsWork->apinfo[gWdsWork->apindex].crc != 0x0000 ) { + OS_TPrintf( "AP Infomation CRC Error.\n" ); + MI_CpuClear8( &gWdsWork->apinfo[gWdsWork->apindex], sizeof(WDSApInfo) ); + continue; + } // その他のデータを設定 - gWdsWork->linklevel[gWdsWork->apnum] = pParam->linkLevel[i]; - gWdsWork->tgid[gWdsWork->apnum] = pParam->bssDesc[i]->gameInfo.tgid; - gWdsWork->apnum = ( gWdsWork->apnum + 1 ) % WDS_APINFO_MAX; + gWdsWork->rssi[gWdsWork->apindex] = WDSGetRssi8( (u8)pParam->bssDesc[i]->rssi ); + gWdsWork->tgid[gWdsWork->apindex] = pParam->bssDesc[i]->gameInfo.tgid; + gWdsWork->apindex = ( gWdsWork->apindex + 1 ) % WDS_APINFO_MAX; + gWdsWork->apnum = ( gWdsWork->apnum + 1 ); + if( gWdsWork->apnum > WDS_APINFO_MAX ) + gWdsWork->apnum = WDS_APINFO_MAX; } } } @@ -226,6 +263,10 @@ int WDS_Initialize( void *wdsWork, WDSCallbackFunc callback, u16 dmaNo ) MI_CpuClear8( gWdsWork, WDS_GetWorkAreaSize() ); gWdsWork->status = WDS_STATUS_INIT; + // CRC計算用コンテキスト・テーブル初期化 + MATH_CRC16Init( &gWdsWork->crcContext ); + MATH_CRC16InitTable( &gWdsWork->crcTable ); + // WM ライブラリ初期化 errcode = WM_Initialize( gWdsWork->wmwork, callback, dmaNo ); if( errcode != WM_ERRCODE_OPERATING ) @@ -272,8 +313,9 @@ int WDS_InitializeEx( void *wdsWork, WDSCallbackFunc callback, u16 dmaNo, WDSBri if( apinfo[i].isvalid == TRUE ) { gWdsWork->apnum++; + gWdsWork->apindex = ( gWdsWork->apindex + 1 ) % WDS_APINFO_MAX; gWdsWork->apinfo[i] = apinfo[i].apinfo; - gWdsWork->linklevel[i] = apinfo[i].rssi; + gWdsWork->rssi[i] = apinfo[i].rssi; } } @@ -425,7 +467,7 @@ int WDS_GetApInfoByIndex( int index, WDSBriefApInfo *briefapinfo ) // その他設定 briefapinfo->isvalid = TRUE; - briefapinfo->rssi = gWdsWork->linklevel[index]; + briefapinfo->rssi = gWdsWork->rssi[index]; MI_CpuCopy8(&gWdsWork->apinfo[index], &briefapinfo->apinfo, sizeof(WDSApInfo)); return 0; @@ -467,6 +509,7 @@ int WDS_GetApInfoAll( WDSBriefApInfo *briefapinfo ) return 0; } +#ifdef WDS_WITHDWC //-------------------------------------------------------------------------------- /** APビーコン情報をDWCの自動接続先として設定します @param <1> 自動接続先として設定するAPビーコン情報のインデックス値(0〜15) @@ -488,7 +531,7 @@ int WDS_SetConnectTargetByIndex( int index ) return -1; // 指定 SSID へ接続 - //DWC_AC_SetSpecifyAp2( gWdsWork->apinfo[index].ssid, (u16)((int)gWdsWork->apinfo[index].channel-1), gWdsWork->apinfo[index].wepkey, gWdsWork->apinfo[index].encryptflag ); + DWC_AC_SetSpecifyAp( gWdsWork->apinfo[index].ssid, gWdsWork->apinfo[index].wepkey, gWdsWork->apinfo[index].encryptflag ); return 0; } @@ -503,8 +546,6 @@ int WDS_SetConnectTargetByIndex( int index ) *///------------------------------------------------------------------------------ int WDS_SetConnectTargetByBriefApInfo( WDSBriefApInfo *briefapinfo ) { -#pragma unused(briefapinfo) - SDK_ASSERT( gWdsWork ); // スキャン中判定 @@ -512,10 +553,11 @@ int WDS_SetConnectTargetByBriefApInfo( WDSBriefApInfo *briefapinfo ) return -1; // 指定 SSID へ接続 - //DWC_AC_SetSpecifyAp2( briefapinfo->apinfo.ssid, (u16)((int)briefapinfo->apinfo.channel-1), briefapinfo->apinfo.wepkey, briefapinfo->apinfo.encryptflag ); + DWC_AC_SetSpecifyAp( briefapinfo->apinfo.ssid, briefapinfo->apinfo.wepkey, briefapinfo->apinfo.encryptflag ); return 0; } +#endif //-------------------------------------------------------------------------------- /** APビーコン情報のAP説明文をUTF-16で得ます diff --git a/build/libraries_sysmenu/wds/readme.txt b/build/libraries_sysmenu/wds/readme.txt new file mode 100644 index 00000000..375045ae --- /dev/null +++ b/build/libraries_sysmenu/wds/readme.txt @@ -0,0 +1,42 @@ +■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ +■ ■ +■ TWLWDSライブラリ 2008/6/11版 ■ +■ ■ +■ ネットワーク開発部からのお知らせ ■ +■ ■ +■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ + +●動作確認バージョン +・SDK +(TwlSDK-5_00fc-080325-1027-branch-5_0fc-TS400_jp) +(TwlSDK-5_00fc-patch-plus4-080609_jp) +(TwlSDK-5_00fcplus2-080428-1417-private-crypto-branch-5_0fcplus2_jp) +・コンパイラ +(CodeWarrior v2.0) +(20080215_cw_ds_2.0_sp2_Buildtools_Patch2.jpSP1) +・デバッグ環境 +(IS-TWL-DEBUGGER Version 0.63.0805.2900) + +●ビルドする際の注意事項 +・ライブラリのビルドは + %make TWLSDK_PLATFORM=TWL +・受信サンプルのビルドはWDSTestディレクトリ下で + %make TWLSDK_PLATFORM=TWL + +●変更履歴 + +2008/06/11 初版 +・動作確認用バージョンから、ビーコンに以下の情報が追加されました + infoflag - 付加情報フラグが格納される領域です + mtu - そのAPが使用可能な最大のMTUを格納されます +・ビーコン受信時にビット誤りが発生した場合には、そのビーコンを無視する + ようになりました。 + +2008/02/21 動作確認用バージョン +・動作確認用として開発技術部にリリース + +●使用時の注意 +infoflagの扱い +・ランチャーメニューでのニンテンドースポットビューアの強調表示は、 + infoflagのWDS_INFOFLAG_NOTIFYビットが1にセットされたビーコンを + 受信した場合のみ行ってください。 diff --git a/build/tests/WDSTest/src/main.c b/build/tests/WDSTest/src/main.c index 17b12e03..add12c99 100644 --- a/build/tests/WDSTest/src/main.c +++ b/build/tests/WDSTest/src/main.c @@ -43,6 +43,7 @@ typedef enum AppState { APP_STATE_WDSENDSCAN, APP_STATE_WDSWAITENDSCAN, APP_STATE_WDSCOMPLETEENDSCAN, + APP_STATE_WDSEND, APP_STATE_WDSWAITEND, APP_STATE_WDSCOMPLETEEND } AppState; @@ -100,17 +101,14 @@ void NitroMain(void) // WDSライブラリの初期化関数を呼び出し、その非同期処理の完了を待つ OS_Printf("*** WDS_Initialize\n"); + g_appstate = APP_STATE_WDSWAITINIT; if( WDS_Initialize( wdsSysBuf, WDS_Initialize_CB, 0 ) == 0 ) { OS_Printf("WDS_Initialize successed\n"); - // コールバックが先に返ってくる場合があるのでその対策 - if( g_appstate < APP_STATE_WDSWAITINIT ) - { - g_appstate = APP_STATE_WDSWAITINIT; - } } else { - OS_Panic("WDS_Initialize failed"); + OS_TPrintf("WDS_Initialize failed"); + g_appstate = APP_STATE_WDSCOMPLETEEND; } break; OS_Printf("*** WDS_Initialize waiting asyncronous process\n"); @@ -127,18 +125,15 @@ void NitroMain(void) //OS_Printf("*** WDS_StartScan\n"); // ビーコンスキャン非同期処理を開始する + g_appstate = APP_STATE_WDSWAITSCAN; if( WDS_StartScan( WDS_StartScan_CB ) == 0 ) { if( wdsScanBeginTick == 0 ) wdsScanBeginTick = OS_GetTick(); - // コールバックが先に返ってくる場合があるのでその対策 - if( g_appstate < APP_STATE_WDSWAITSCAN ) - { - g_appstate = APP_STATE_WDSWAITSCAN; - } } else { - OS_Panic("WDS_StartScan failed"); + OS_TPrintf("WDS_EndScan failed"); + g_appstate = APP_STATE_WDSEND; } break; case APP_STATE_WDSCOMPLETESCAN: @@ -161,17 +156,14 @@ void NitroMain(void) OS_Printf("*** WDS_EndScan\n"); // スキャンを終了させる非同期処理を開始する + g_appstate = APP_STATE_WDSWAITENDSCAN; if( WDS_EndScan( WDS_EndScan_CB ) == 0 ) { OS_Printf("WDS_EndScan successed\n"); - // コールバックが先に返ってくる場合があるのでその対策 - if( g_appstate < APP_STATE_WDSWAITENDSCAN ) - { - g_appstate = APP_STATE_WDSWAITENDSCAN; - } } else { - OS_Panic("WDS_EndScan failed"); + OS_TPrintf("WDS_EndScan failed"); + g_appstate = APP_STATE_WDSEND; } break; case APP_STATE_WDSCOMPLETEENDSCAN: @@ -189,17 +181,15 @@ void NitroMain(void) DumpWDSApInfo( &briefapinfo[i].apinfo ); } } - + g_appstate = APP_STATE_WDSEND; + break; + case APP_STATE_WDSEND: // WDSライブラリを終了し、無線ハードの電源を落とす非同期処理を開始する OS_Printf("*** WDS_End\n"); + g_appstate = APP_STATE_WDSWAITEND; if( WDS_End( WDS_End_CB ) == 0 ) { OS_Printf("WDS_End successed\n"); - // コールバックが先に返ってくる場合があるのでその対策 - if( g_appstate < APP_STATE_WDSWAITEND ) - { - g_appstate = APP_STATE_WDSWAITEND; - } } else { OS_Panic("WDS_End failed"); @@ -208,7 +198,7 @@ void NitroMain(void) case APP_STATE_WDSCOMPLETEEND: // WDSライブラリの解放処理が完了した際に入って来るステート - OS_TPrintf("WDS test successfully completed\n"); + OS_TPrintf("WDS completed\n"); OS_Terminate(); } } diff --git a/include/sysmenu/WDS.h b/include/sysmenu/WDS.h index addcc443..ac1c841d 100644 --- a/include/sysmenu/WDS.h +++ b/include/sysmenu/WDS.h @@ -50,6 +50,12 @@ extern "C" { */ #define WDS_APINFO_MAX 16 +/** + @brief 親機情報フラグ定義 +*/ +#define WDS_INFOFLAG_NOTIFY (0x01) ///< 通知フラグ +#define WDS_INFOFLAG_ALLOWAUTOCONNECT (0x01 << 1) ///< インターネットフルアクセス可能フラグ + //----------------------------------------------------- // Types //----------------------------------------------------- @@ -73,7 +79,10 @@ typedef struct WDSApInfo u8 wepkey[ WDS_WEPKEY_BUF_SIZE ]; ///< 親機が接続するAPのWEP キー u8 channel; ///< 親機が接続したAPが使っているチャンネル u8 encryptflag; ///< AP接続時にNitroWiFiが使う暗号化方式 - u8 reserve[10]; ///< 予約領域 + u8 infoflag; ///< 親機の接続するネットの特性を記録するフラグ領域 + u8 reserve[ 5 ]; ///< 予約領域 + u16 mtu; ///< 使用可能なMTU + u16 crc; ///< CRC } WDSApInfo; /** @@ -83,7 +92,7 @@ typedef struct WDSBriefApInfo { // WDSライブラリによって生成される値 BOOL isvalid; - u16 rssi; ///< 電波強度 + u16 rssi; ///< 電波強度 // AP情報ビーコンそのもの WDSApInfo apinfo; @@ -198,6 +207,7 @@ int WDS_GetApInfoByIndex( int index, WDSBriefApInfo *briefapinfo ); *///------------------------------------------------------------------------------ int WDS_GetApInfoAll( WDSBriefApInfo *briefapinfo ); +#ifdef WDS_WITHDWC //-------------------------------------------------------------------------------- /** APビーコン情報をDWCの自動接続先として設定します @param <1> 自動接続先として設定するAPビーコン情報のインデックス値(0〜15) @@ -217,7 +227,8 @@ int WDS_SetConnectTargetByIndex( int index ); スキャン中に実行した場合はエラー値を返します。 *///------------------------------------------------------------------------------ int WDS_SetConnectTargetByBriefApInfo( WDSBriefApInfo *briefapinfo ); - +#endif + //-------------------------------------------------------------------------------- /** APビーコン情報のAP説明文をUTF-16で得ます @param <1> AP説明文を取得する対象のAPビーコン情報