diff --git a/bin/ARM9-TS/Release/wds/BACKUPDATA_FOR_RED.bin b/bin/ARM9-TS/Release/wds/BACKUPDATA_FOR_RED.bin new file mode 100644 index 00000000..bfe330c0 Binary files /dev/null and b/bin/ARM9-TS/Release/wds/BACKUPDATA_FOR_RED.bin differ diff --git a/bin/ARM9-TS/Release/wds/basestation.srl b/bin/ARM9-TS/Release/wds/basestation.srl new file mode 100644 index 00000000..d212a8c3 Binary files /dev/null and b/bin/ARM9-TS/Release/wds/basestation.srl differ diff --git a/bin/ARM9-TS/Release/wds/browser.srl b/bin/ARM9-TS/Release/wds/browser.srl new file mode 100644 index 00000000..58caa77a Binary files /dev/null and b/bin/ARM9-TS/Release/wds/browser.srl differ diff --git a/bin/ARM9-TS/Release/wds/readme.txt b/bin/ARM9-TS/Release/wds/readme.txt new file mode 100644 index 00000000..9022af34 --- /dev/null +++ b/bin/ARM9-TS/Release/wds/readme.txt @@ -0,0 +1,51 @@ +ステップ1: 親機を動作させ、ビーコンを送信する +1. 2MフラッシュサブカードのついたDSフラッシュカードを準備します +2. バックアップデバイスにBACKUPDATA_FOR_RED.binを書き込んでください +3. DSフラッシュカードにbasestation.srlを書き込んでください +4. DSフラッシュカードを通常のDSに挿し、起動してください + (IS-NITRO-DEBUGGERを使うとトラブルシュートがしやすくなります) +5. 下画面に「サーバとインターネット経由で通信中」と表示されたら正常にイ +ンターネットと通信できています +6. しばらくたつと下画面に「DSの接続を待っています」と表示されます +7. この状態で親機はAP情報ビーコンを送信しています。 + +ステップ2: WDS組み込み済み店頭ブラウザ(DS版)でビーコン送信が正常であるこ +とを確認する +1. DSフラッシュカードを準備します +2. DSフラッシュカードにbrowser.srlを書き込んでください +3. DSフラッシュカードを通常のDSに挿し、起動してください + (IS-NITRO-DEBUGGERを使うとトラブルシュートがしやすくなります) +4. DSは自動的に店頭配信サーバに接続します。体験版等をダウンロードする画 +面が表示されれば正常です。 + +ステップ3: TWL用WDSライブラリのサンプルを動作させる +1. WDS080221.zipを解凍してください +2. WDS/WDSTest/bin/ARM9-TS.HYB/Release/main.srlをTWLデバッガで動かします +3. デバッグ画面にビーコンの内容が出力され、動作の確認は終了です + +以下WDSライブラリの簡単な説明です。 + +WDSライブラリはWMライブラリのラッパーとして動作します。そのため非常にシ +ンプルな構造となっております。 + +関数のリファレンスに関してはWDS/include/WDS.hにDoxygen準拠のコメントが付 +いていますので、そちらをご覧いただければよいかと思います。 + +WDSライブラリを動作させる流れは、 + +1. WDS_Initialize関数でライブラリを初期化します +2. WDS_StartScan関数でビーコンスキャン開始、この処理は非同期処理で、完了 +時にユーザーが与えたコールバック関数が呼び出されます +3. スキャンは非常に短い時間で終了します。1回のスキャンではビーコンが取れ +ないことが多いため、ユーザーは想定するスキャン時間が過ぎるまで、スキャン +完了コールバックを受けたら、再びWDS_StartScan関数を呼び出すことを繰り返 +します +4. WDS_GetApInfoNum関数を使い、取得できたビーコンの数を得ることができま +す。これとWDS_GetApInfoAll関数を組み合わせて、受信したビーコンの情報を取 +り出してください。 +5. DSであれば、取得したビーコンをDWC_SetSpecifyAp2関数に与えて呼び出すこ +とでACの自動接続先としてビーコンに含まれている情報を設定できるのですが、 +TWLではDWCが移植されていないため、ここはコメントアウトされています。 + +というようなものです。WDS/WDSTest/src/main.cに非常にシンプルなソースがあ +りますので、確認にご利用下さい。 diff --git a/build/libraries_sysmenu/Makefile b/build/libraries_sysmenu/Makefile index 7bd41f8c..15e87a59 100644 --- a/build/libraries_sysmenu/Makefile +++ b/build/libraries_sysmenu/Makefile @@ -22,7 +22,17 @@ include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs #---------------------------------------------------------------------------- -SUBDIRS_P = reloc_info sysmenu mb_loader acsign boot hotsw namut mcu ds dht +SUBDIRS_P = reloc_info \ + sysmenu \ + mb_loader \ + acsign \ + boot \ + hotsw \ + namut \ + mcu \ + ds \ + dht \ + wds #---------------------------------------------------------------------------- diff --git a/build/libraries_sysmenu/wds/ARM9/Makefile b/build/libraries_sysmenu/wds/ARM9/Makefile new file mode 100644 index 00000000..786f9620 --- /dev/null +++ b/build/libraries_sysmenu/wds/ARM9/Makefile @@ -0,0 +1,49 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlIPL +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Date:: $ +# $Rev$ +# $Author$ +#---------------------------------------------------------------------------- + +#------------------------------------------------------------------ +# +# WDS Library Makefile +# +#------------------------------------------------------------------ +#! make -f + +TARGET_FIRM = SYSTEMMENU +TARGET_PLATFORM = TWL +TWL_ARCHGEN = LIMITED +TWL_PROC = ARM9 + +SUBDIRS = + +SRCS = WDS.c + +TARGET_LIB = WDS$(TWL_LIBSUFFIX).a + +LINCLUDES = + +INSTALL_TARGETS = $(TARGETS) +INSTALL_DIR = $(SYSMENU_INSTALL_LIBDIR) + +#---------------------------------------------------------------------------- +include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs + +do-build: $(TARGETS) + +include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules + +#===== End of Makefile ===== diff --git a/build/libraries_sysmenu/wds/ARM9/src/WDS.c b/build/libraries_sysmenu/wds/ARM9/src/WDS.c new file mode 100644 index 00000000..424de9e6 --- /dev/null +++ b/build/libraries_sysmenu/wds/ARM9/src/WDS.c @@ -0,0 +1,558 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL + File: WDS.c + + Copyright 2007 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +//********************************************************************** +/** +// @file WDS.c +// @brief 店頭親機がMP送信する接続先AP情報を受信 +// +// @author M.Okuno +// @date 2008/02/05 +// @version 01.00 +// +***********************************************************************/ +#include +#include + +//----------------------------------------------------- +// Macros +//----------------------------------------------------- +/** + @brief スキャンバッファサイズ +*/ +#define WDS_SCAN_BUF_SIZE 1024 + +/** + @brief 親機AP情報GGID +*/ +#define WDS_APINFO_GGID 0x00000857 + +/** + @brief ステータス +*/ +enum +{ + WDS_STATUS_INIT , ///< 初期化中 + WDS_STATUS_STARTSCAN , ///< スキャン開始 + WDS_STATUS_ENDSCAN , ///< スキャン終了 + WDS_STATUS_END ///< 終了 +}; + +//----------------------------------------------------- +// Structs +//----------------------------------------------------- +/** + @brief ワーク領域 +*/ +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; +} WDSWork; + +//----------------------------------------------------- +// Variables +//----------------------------------------------------- +static WDSWork *gWdsWork = NULL; + +//-------------------------------------------------------------------------------- +/** UTF8 → UCS2 へ変換します + @param <1> UTF8 文字 + @param <2> バイト判定 + @return UCS2 文字 + @note + browse_unicode.cpp から移植。 +*///------------------------------------------------------------------------------ +static u16 bu_UTF8_To_UCS2( const u8 *c, s32 *bytes_used ) +{ + u16 ret; + u8 b1, b2, b3; + + if( (*c & 0x80) == 0 ) { + // 1バイト、ASCII + ret = *c; + *bytes_used = 1; + } + else if( (*c & 0xe0) == 0xc0 ) { + // 2バイト、欧州文字とか? + b1 = (u8)(c[0] & 0x1f); + b2 = (u8)(c[1] & 0x3f); + ret = (u16)(( b1 << 6 ) | b2 ); + *bytes_used = 2; + } + else if( (*c & 0xf0) == 0xe0 ) { + // 3バイト、日本語はここかな + b1 = (u8)(c[0] & 0x0f); + b2 = (u8)(c[1] & 0x3f); + b3 = (u8)(c[2] & 0x3f); + ret = (u16)(( b1 << 12 ) | ( b2 << 6 ) | b3 ); + *bytes_used = 3; + } + else { + // 想定外の値の場合、ASCIIのハテナを返しとく + ret = 0x3F; + *bytes_used = 1; + } + return ret; +} + +//-------------------------------------------------------------------------------- +/** WM_StartScanEx() 用コールバック + @param <1> パラメータ +*///------------------------------------------------------------------------------ +static void WDSScanCallback( void *arg ) +{ + WMStartScanExCallback *pParam = (WMStartScanExCallback*)arg; + u32 i, j; + + // スキャンの結果得られたデータはARM7からDMA経由でメインメモリに直接書き込まれる + // そのためARM9のデータキャッシュをいったん無効化しなければデータを正常に読めないことに注意 + DC_InvalidateRange(gWdsWork->scanbuf, WDS_SCAN_BUF_SIZE); + + // 親機を発見したか判定 + if( pParam->errcode == WM_ERRCODE_SUCCESS && pParam->state == WM_STATECODE_PARENT_FOUND ) { + // 発見した親機の中に店頭用親機があるか検索 + for( i = 0 ; i < pParam->bssDescCount ; i++ ) { + // GGID 判定 + if( WM_IsValidGameInfo( &pParam->bssDesc[i]->gameInfo, sizeof(WMGameInfo) ) && pParam->bssDesc[i]->gameInfo.ggid == WDS_APINFO_GGID ) { + // AP 情報発見 + CRYPTORC4FastContext rc4context; + u8 rc4key[ 8 ]; + BOOL duplicated; + const u32 magic = 'WDS!'; + + // ビーコンの重複チェック + duplicated = FALSE; + for( j = 0 ; j < gWdsWork->apnum ; j++ ) + { + if( gWdsWork->tgid[j] == pParam->bssDesc[i]->gameInfo.tgid ) + { + duplicated = TRUE; + break; + } + } + if( duplicated == TRUE ) + continue; + + // デバッグ表示 + 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( &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] ); + + // その他のデータを設定 + 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->status = WDS_STATUS_ENDSCAN; + + // コールバック実行 + if( gWdsWork->scancb ) + gWdsWork->scancb( arg ); +} + +//-------------------------------------------------------------------------------- +/** WDSライブラリが使用するワークエリアのサイズを得ます + @return 0 以外 : ワークエリアのサイズ + @note + ライブラリ初期化時に使用します +*///------------------------------------------------------------------------------ +size_t WDS_GetWorkAreaSize( void ) +{ + return sizeof( WDSWork ); +} + +//-------------------------------------------------------------------------------- +/** WDSを初期化します + @param <1> 呼び出し元によって確保されたバッファへのポインタを指定します + @param <2> 処理が完了した際に呼び出されるコールバック関数へのポインタ + @param <3> WM_InitializeのdmaNoに準ずる引数 + @return 0 : 成功 ( コールバックを待つこと ) + 0 以外 : 失敗 + @note + <1> のサイズはWDS_SYSTEM_BUF_SIZEだけ必要であり、 + かつ 32バイトアラインされている必要があります。 + <2> のコールバックは割り込みハンドラ内から呼び出されます。 + WDS 関連のコールバック関数内では呼び出せません。 + 関数内部でWM_Initialize()を実行する為、WMはREADYステートからIDLEステートに移行します。 +*///------------------------------------------------------------------------------ +int WDS_Initialize( void *wdsWork, WDSCallbackFunc callback, u16 dmaNo ) +{ + WMErrCode errcode; + + SDK_ASSERT( wdsWork ); + + if( callback == NULL ) + return -1; + + // ワーク用バッファ設定 + gWdsWork = (WDSWork*)wdsWork; + + // メモリ初期化 + MI_CpuClear8( gWdsWork, WDS_GetWorkAreaSize() ); + gWdsWork->status = WDS_STATUS_INIT; + + // WM ライブラリ初期化 + errcode = WM_Initialize( gWdsWork->wmwork, callback, dmaNo ); + if( errcode != WM_ERRCODE_OPERATING ) + return errcode; + return 0; +} + + +//-------------------------------------------------------------------------------- +/** WDSを初期化します(指定したスキャン結果を内部的に保持した状態での初期化) + @param <1> 呼び出し元によって確保されたバッファへのポインタを指定します + @param <2> 処理が完了した際に呼び出されるコールバック関数へのポインタ + @param <3> WM_InitializeのdmaNoに準ずる引数 + @param <4> 事前にWDSを使用して取得したWDSBriefInfoの配列 + @return 0 : 成功 ( コールバックを待つこと ) + 0 以外 : 失敗 + @note + <1> のサイズはWDS_SYSTEM_BUF_SIZEだけ必要であり、 + かつ 32バイトアラインされている必要があります。 + <2> のコールバックは割り込みハンドラ内から呼び出されます。 + WDS 関連のコールバック関数内では呼び出せません。 + 関数内部でWM_Initialize()を実行する為、WMはREADYステートからIDLEステートに移行します。 +*///------------------------------------------------------------------------------ +int WDS_InitializeEx( void *wdsWork, WDSCallbackFunc callback, u16 dmaNo, WDSBriefApInfo *apinfo ) +{ + WMErrCode errcode; + int i; + + SDK_ASSERT( wdsWork ); + + if( callback == NULL ) + return -1; + + // ワーク用バッファ設定 + gWdsWork = (WDSWork*)wdsWork; + + // メモリ初期化 + MI_CpuClear8( gWdsWork, WDS_GetWorkAreaSize() ); + gWdsWork->status = WDS_STATUS_INIT; + + // 初期値をコピー + for( i = 0 ; i < WDS_APINFO_MAX ; i++ ) + { + if( apinfo[i].isvalid == TRUE ) + { + gWdsWork->apnum++; + gWdsWork->apinfo[i] = apinfo[i].apinfo; + gWdsWork->linklevel[i] = apinfo[i].rssi; + } + } + + // WM ライブラリ初期化 + errcode = WM_Initialize( gWdsWork->wmwork, callback, dmaNo ); + if( errcode != WM_ERRCODE_OPERATING ) + return errcode; + + // 初期値を入れた関係上、ステータスをスキャン完了にする + gWdsWork->status = WDS_STATUS_ENDSCAN; + + return 0; +} + +//-------------------------------------------------------------------------------- +/** WDSを終了します + @param <1> 処理が完了した際に呼び出されるコールバック関数へのポインタ + @return 0 : 成功 ( コールバックを待つこと ) + 0 以外 : 失敗 + @note + <1> のコールバックは割り込みハンドラ内から呼び出されます。 + WDS 関連のコールバック関数内では呼び出せません。 +*///------------------------------------------------------------------------------ +int WDS_End( WDSCallbackFunc callback ) +{ + WMErrCode errcode; + + if( callback == NULL ) + return -1; + + // WDS 終了 + gWdsWork->status = WDS_STATUS_END; + gWdsWork = NULL; + + // WM 終了 + errcode = WM_End( callback ); + if( errcode != WM_ERRCODE_OPERATING ) + return errcode; + return 0; +} + +//-------------------------------------------------------------------------------- +/** DS配信システム親機ビーコンをスキャンを開始します + @param <1> 処理が完了した際に呼び出されるコールバック関数へのポインタ + @return 0 : 成功 ( コールバックを待つこと ) + 0 以外 : 失敗 + @note + <1> のコールバックは割り込みハンドラ内から呼び出されます。 + WDS 関連のコールバック関数内では呼び出せません。 + 関数内部でWM_StartScane()を実行する為、WMはIDLEステートの場合はSCANステートに移行します。 +*///------------------------------------------------------------------------------ +int WDS_StartScan( WDSCallbackFunc callback ) +{ + WMErrCode errcode; + + SDK_ASSERT( gWdsWork ); + + if( callback == NULL ) + return -1; + + // スキャンパラメータ設定 + // スキャンチャンネルは 1, 7, 13 + // 300ms〜600ms スキャンを行う + gWdsWork->scanparam.scanBuf = (WMBssDesc*)&gWdsWork->scanbuf; + gWdsWork->scanparam.scanBufSize = WDS_SCAN_BUF_SIZE; + gWdsWork->scanparam.channelList = WM_GetAllowedChannel(); + gWdsWork->scanparam.maxChannelTime = WM_GetDispersionScanPeriod(); + gWdsWork->scanparam.scanType = WM_SCANTYPE_PASSIVE; + MI_CpuFill8( gWdsWork->scanparam.bssid, 0xFF, WDS_MACADDR_BUF_SIZE ); + + // コールバック保存 + gWdsWork->scancb = callback; + + // スキャン開始 + gWdsWork->status = WDS_STATUS_STARTSCAN; + errcode = WM_StartScanEx( WDSScanCallback, &gWdsWork->scanparam ); + if( errcode != WM_ERRCODE_OPERATING ) + return errcode; + return 0; +} + +//-------------------------------------------------------------------------------- +/** DS配信システム親機ビーコンをスキャンを終了します + @param <1> 処理が完了した際に呼び出されるコールバック関数へのポインタ + @return 0 : 成功 ( コールバックを待つこと ) + 0 以外 : 失敗 + @note + <1> のコールバックは割り込みハンドラ内から呼び出されます。 + WDS 関連のコールバック関数内では呼び出せません。 + 関数内部でWM_EndScan()を実行する為、WMはIDLEステートに移行します。 +*///------------------------------------------------------------------------------ +int WDS_EndScan( WDSCallbackFunc callback ) +{ + WMErrCode errcode; + + SDK_ASSERT( gWdsWork ); + + if( callback == NULL ) + return -1; + + // スキャン終了 + gWdsWork->status = WDS_STATUS_ENDSCAN; + errcode = WM_EndScan( callback ); + if( errcode != WM_ERRCODE_OPERATING ) + return errcode; + return 0; +} + +//-------------------------------------------------------------------------------- +/** APビーコン情報の数を取得します + @return 0 以上 : 成功 + 0 未満 : 失敗 ( スキャン中 ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_GetApInfoNum( void ) +{ + SDK_ASSERT( gWdsWork ); + + // スキャン中判定 + if( gWdsWork->status != WDS_STATUS_ENDSCAN ) + return -1; + return gWdsWork->apnum; +} + +//-------------------------------------------------------------------------------- +/** APビーコン情報をインデックスを指定して取得します + @param <1> 取得するAPビーコン情報のインデックス値(0〜15) + @param <2> 取得するAPビーコン情報を書き込む領域へのポインタ + @return 0 : 成功 + 0 以外 : 失敗 ( スキャン中、又はインデックスの示す位置にデータがない ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_GetApInfoByIndex( int index, WDSBriefApInfo *briefapinfo ) +{ + SDK_ASSERT( gWdsWork ); + + // スキャン中判定 + if( gWdsWork->status != WDS_STATUS_ENDSCAN ) + return -1; + + // インデックスエラー判定 + if( index < 0 || index >= gWdsWork->apnum ) + return -1; + + // メモリ初期化 + MI_CpuClear8( briefapinfo, sizeof(WDSBriefApInfo) ); + + // その他設定 + briefapinfo->isvalid = TRUE; + briefapinfo->rssi = gWdsWork->linklevel[index]; + MI_CpuCopy8(&gWdsWork->apinfo[index], &briefapinfo->apinfo, sizeof(WDSApInfo)); + + return 0; +} + +//-------------------------------------------------------------------------------- +/** APビーコン情報を全て取得します + @param <1> 取得するAPビーコン情報を書き込む配列の先頭へのポインタ(WDS_APINFO_MAX個の要素が必要) + @return 0 : 成功 + 0 以外 : 失敗 ( スキャン中、又はインデックスの示す位置にデータがない ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_GetApInfoAll( WDSBriefApInfo *briefapinfo ) +{ + int index; + + SDK_ASSERT( gWdsWork ); + + // スキャン中判定 + if( gWdsWork->status != WDS_STATUS_ENDSCAN ) + return -1; + + // メモリ初期化 + MI_CpuClear8( briefapinfo, sizeof(WDSBriefApInfo)*WDS_APINFO_MAX ); + for( index = 0 ; index < WDS_APINFO_MAX ; index++ ) + { + briefapinfo[index].isvalid = FALSE; + } + + // 指定インデックスのAPビーコン情報をコピー + // ホットスポット名を設定 ( UTF-8 の場合は UTF-16 に変換 ) + // 全てのAPビーコン情報をコピー + for( index = 0 ; index < gWdsWork->apnum ; index++ ) { + if( WDS_GetApInfoByIndex( index, briefapinfo+index ) == -1 ) + break; + } + + return 0; +} + +//-------------------------------------------------------------------------------- +/** APビーコン情報をDWCの自動接続先として設定します + @param <1> 自動接続先として設定するAPビーコン情報のインデックス値(0〜15) + @return 0 : 成功 + 0 以外 : 失敗 ( スキャン中、又はインデックスの示す位置にデータがない ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_SetConnectTargetByIndex( int index ) +{ + SDK_ASSERT( gWdsWork ); + + // スキャン中判定 + if( gWdsWork->status != WDS_STATUS_ENDSCAN ) + return -1; + + // インデックスエラー判定 + if( index < 0 || index >= gWdsWork->apnum ) + 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 ); + + return 0; +} + +//-------------------------------------------------------------------------------- +/** APビーコン情報をDWCの自動接続先として設定します + @param <1> 自動接続先として設定するAPビーコン情報 + @return 0 : 成功 + 0 以外 : 失敗 ( スキャン中、又はインデックスの示す位置にデータがない ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_SetConnectTargetByBriefApInfo( WDSBriefApInfo *briefapinfo ) +{ +#pragma unused(briefapinfo) + + SDK_ASSERT( gWdsWork ); + + // スキャン中判定 + if( gWdsWork->status != WDS_STATUS_ENDSCAN ) + return -1; + + // 指定 SSID へ接続 + //DWC_AC_SetSpecifyAp2( briefapinfo->apinfo.ssid, (u16)((int)briefapinfo->apinfo.channel-1), briefapinfo->apinfo.wepkey, briefapinfo->apinfo.encryptflag ); + + return 0; +} + +//-------------------------------------------------------------------------------- +/** APビーコン情報のAP説明文をUTF-16で得ます + @param <1> AP説明文を取得する対象のAPビーコン情報 + <2> AP説明文を書き込むバッファへのポインタ(WDS_HOTSPOTNAME_UTF16_BUF_SIZEバイト) + @return 0 : 成功 + 0 以外 : 失敗 ( スキャン中、又はインデックスの示す位置にデータがない ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_GetApDescriptionUTF16( WDSBriefApInfo *briefapinfo, void *outbuf ) +{ + SDK_ASSERT( briefapinfo->isvalid ); + + // バッファをクリア + MI_CpuClear8( outbuf, WDS_HOTSPOTNAME_UTF16_BUF_SIZE ); + + // 指定インデックスのAPビーコン情報をコピー + // ホットスポット名を設定 ( UTF-8 の場合は UTF-16 に変換 ) + if( (briefapinfo->apinfo.hotspotid & WDS_HOTSPOT_ENCODE_MASK) == WDS_HOTSPOT_ENCODE_UTF8 ) { + // UTF-8 + u8 *pStr = briefapinfo->apinfo.hotspotname; + u8 *pEndStr = briefapinfo->apinfo.hotspotname + WDS_HOTSPOTNAME_BUF_SIZE; + u16 *pUcs2 = (u16*)outbuf; + s32 temp; + + // UTF-16に変換 + while( pStr != pEndStr && *pStr != '\0' ) { + *pUcs2 = bu_UTF8_To_UCS2( pStr, &temp ); + pStr += temp; + pUcs2 += 1; + } + } + else { + // UTF-16 + MI_CpuCopy8( briefapinfo->apinfo.hotspotname, outbuf, WDS_HOTSPOTNAME_BUF_SIZE ); + } + + return 0; +} diff --git a/build/libraries_sysmenu/wds/Makefile b/build/libraries_sysmenu/wds/Makefile new file mode 100644 index 00000000..a2098ba3 --- /dev/null +++ b/build/libraries_sysmenu/wds/Makefile @@ -0,0 +1,33 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlIPL +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Date:: $ +# $Rev$ +# $Author$ +#---------------------------------------------------------------------------- + +TARGET_FIRM = SYSTEMMENU + +include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +SUBDIRS = ARM9 + +#---------------------------------------------------------------------------- + +include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/systemMenu_RED/Launcher/ARM9/Makefile b/build/systemMenu_RED/Launcher/ARM9/Makefile index d9c7b40a..d5b09e31 100644 --- a/build/systemMenu_RED/Launcher/ARM9/Makefile +++ b/build/systemMenu_RED/Launcher/ARM9/Makefile @@ -17,9 +17,9 @@ #---------------------------------------------------------------------------- SUBDIRS = \ - ../../../libraries_sysmenu/sysmenu \ - ../../../libraries_sysmenu/boot \ - ../../../components/hyena.TWL +# ../../../libraries_sysmenu/sysmenu \ +# ../../../libraries_sysmenu/boot \ +# ../../../components/hyena.TWL # ../../../libraries_sysmenu/hotsw \ # ../../../libraries_sysmenu/reloc_info \ # ../../../libraries_sysmenu/mcu \ @@ -57,7 +57,7 @@ MISC_DIR = ../../misc BG_DIR = ../../data SRCS_LOGO = logoDemo.c logoData.c -SRCS = main.c launcher.c sound.c bannerCounter.c loadWlanFirm.c \ +SRCS = main.c launcher.c sound.c bannerCounter.c loadWlanFirm.c scanWDS.c \ $(addprefix $(LOGO_DIR)/, $(SRCS_LOGO)) \ $(MISC_DIR)/src/misc.c $(MISC_DIR)/src/cmn.c \ $(BG_DIR)/BGData_Launcher.c @@ -71,7 +71,8 @@ LLIBRARIES += libes$(TWL_LIBSUFFIX).a \ libboc$(TWL_LIBSUFFIX).a \ libnam$(TWL_LIBSUFFIX).a \ libsea$(TWL_LIBSUFFIX).a \ - libreloc_info$(TWL_LIBSUFFIX).a + libreloc_info$(TWL_LIBSUFFIX).a \ + WDS$(TWL_LIBSUFFIX).a ADDRESS_DTCM = 0x0e000000 diff --git a/build/systemMenu_RED/Launcher/ARM9/src/loadWlanFirm.c b/build/systemMenu_RED/Launcher/ARM9/src/loadWlanFirm.c index 3f29292b..fbbab057 100644 --- a/build/systemMenu_RED/Launcher/ARM9/src/loadWlanFirm.c +++ b/build/systemMenu_RED/Launcher/ARM9/src/loadWlanFirm.c @@ -27,6 +27,7 @@ #include "nwm_arm9_private.h" #include "loadWlanFirm.h" +#include "scanWDS.h" /* definitions @@ -218,6 +219,19 @@ s32 ReadFirmwareBinary(char *path, u32 offset, u8 *buffer, s32 bufSize) return flen; } +#ifdef SDK_RELEASE +static const u8 s_pubkey9_1[ 0x80 ] = { + 0xb6, 0x18, 0xd8, 0x61, 0x28, 0xcb, 0x5c, 0x6f, 0x05, 0xfc, 0xd7, 0x09, 0x18, 0x3f, 0xb2, 0xd0, + 0x6b, 0x7d, 0xee, 0xd9, 0x98, 0xdc, 0x4f, 0xdd, 0xc1, 0xa8, 0x59, 0x18, 0xfb, 0xb0, 0x65, 0xbd, + 0x65, 0x80, 0x9c, 0xc7, 0x68, 0xa1, 0x4e, 0xdc, 0x18, 0xaa, 0x7b, 0xcb, 0xb9, 0xa0, 0x7c, 0xfc, + 0x1f, 0xab, 0x86, 0x5d, 0xed, 0x9c, 0x2c, 0x5c, 0x6d, 0x07, 0xd9, 0xfc, 0xc2, 0x9b, 0x7a, 0x9d, + 0x7c, 0x3a, 0x73, 0x33, 0xb7, 0xe8, 0x04, 0x86, 0x81, 0xc8, 0x5c, 0x7d, 0xb3, 0x95, 0x7d, 0xc9, + 0xec, 0x66, 0x07, 0x2f, 0x8b, 0xb2, 0x6d, 0x13, 0xc4, 0x6c, 0xf0, 0xba, 0x27, 0x82, 0x33, 0x18, + 0xd4, 0x31, 0x6a, 0xb2, 0xad, 0xbc, 0x37, 0x06, 0x6a, 0x2e, 0xe9, 0x73, 0x5f, 0x3a, 0x57, 0xc7, + 0xd7, 0xf8, 0x8e, 0xc1, 0xb9, 0x3d, 0x3f, 0xd4, 0xe5, 0x27, 0x6f, 0xb4, 0x00, 0x8b, 0xb7, 0x19, +}; +#endif + BOOL VerifyWlanfirmSignature(u8* buffer, u32 length) { #pragma unused(length) @@ -234,8 +248,14 @@ BOOL VerifyWlanfirmSignature(u8* buffer, u32 length) #if (MEASURE_VERIFY_SIGN_TIME == 1) OSTick vstart = OS_GetTick(); #endif - + +#ifdef SDK_RELEASE + // ランチャー経由でのデバッガ起動では、鍵情報を受け取ることができない。 + // よってリリースビルドの時は、デバッグ動作を優先して鍵を自分で持つ。 + pPubkey = (u8 *)s_pubkey9_1; +#else pPubkey = OSi_GetFromFirmAddr()->rsa_pubkey[WLANFIRM_PUBKEY_INDEX]; +#endif pSign = (u8*)((u32)buffer + (u32)hdr->soffset); txt = buffer; @@ -540,7 +560,7 @@ BOOL GetWlanFirmwareInstallResult(WLANFirmResult *pResult) } // 無線ファームロード完了? -BOOL PollingInstallWlanFirmware( void ) +BOOL PollingInstallWlanFirmware( BOOL isStartScanWDS ) { if ( !s_isFinished ) { WLANFirmResult result; @@ -557,6 +577,12 @@ BOOL PollingInstallWlanFirmware( void ) SYSMi_SetWirelessLED( enable ); #endif OS_TPrintf( "WLFIRM load finished.\n" ); + + // WDSスキャンがTRUE かつ 無線フラグがONならば、引き続きWDSビーコン受信開始 + if( isStartScanWDS && + !LCFG_THW_IsForceDisableWireless() && LCFG_TSD_IsAvailableWireless() ) { + StartScanWDS(); + } }else { // ロード失敗 if( !s_isHotStartWLFirm ) { diff --git a/build/systemMenu_RED/Launcher/ARM9/src/loadWlanFirm.h b/build/systemMenu_RED/Launcher/ARM9/src/loadWlanFirm.h index d595675e..7beff702 100644 --- a/build/systemMenu_RED/Launcher/ARM9/src/loadWlanFirm.h +++ b/build/systemMenu_RED/Launcher/ARM9/src/loadWlanFirm.h @@ -50,7 +50,7 @@ BOOL InstallWlanFirmware( BOOL isHotStartWLFirm ); FALSE … 無線ファームウェアインストール処理が未完了 */ -BOOL PollingInstallWlanFirmware( void ); +BOOL PollingInstallWlanFirmware( BOOL isStartScanWDS ); #ifdef __cplusplus diff --git a/build/systemMenu_RED/Launcher/ARM9/src/main.c b/build/systemMenu_RED/Launcher/ARM9/src/main.c index 43372a91..84f36884 100644 --- a/build/systemMenu_RED/Launcher/ARM9/src/main.c +++ b/build/systemMenu_RED/Launcher/ARM9/src/main.c @@ -289,7 +289,7 @@ void TwlMain( void ) break; case AUTHENTICATE: if( ( direct_boot || ( !direct_boot && LauncherFadeout( s_titleList ) ) ) && - PollingInstallWlanFirmware() && // アプリブート前に無線ファームのロードは完了しておく必要がある + PollingInstallWlanFirmware( FALSE ) && // アプリブート前に無線ファームのロードは完了しておく必要がある SYSM_IsAuthenticateTitleFinished() ) { if( SYSM_IsFatalError() ) { @@ -315,7 +315,7 @@ void TwlMain( void ) (void)SYSM_GetCardTitleList( s_titleList ); // 無線ファームロードのポーリング - (void)PollingInstallWlanFirmware(); + (void)PollingInstallWlanFirmware( pBootTitle ? FALSE : TRUE ); // コマンドフラッシュ (void)SND_FlushCommand(SND_COMMAND_NOBLOCK); diff --git a/build/systemMenu_RED/Launcher/ARM9/src/scanWDS.c b/build/systemMenu_RED/Launcher/ARM9/src/scanWDS.c new file mode 100644 index 00000000..44375cdd --- /dev/null +++ b/build/systemMenu_RED/Launcher/ARM9/src/scanWDS.c @@ -0,0 +1,260 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL + File: scanWDS.c + + Copyright 2007 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include "scanWDS.h" + +#define WDS_THREAD_PRIO 10 +#define WDS_STACK_SIZE 1024 +#define WDS_MESG_DEPTH 1 +static OSThread s_thread; +u64 s_stack[ WDS_STACK_SIZE / sizeof(u64) ]; +OSMessage s_msgBuffer[ WDS_MESG_DEPTH ]; +OSMessageQueue s_msgQueue; + +// WDSスキャンスレッド +static void ScanWDSThread( void *arg ); +// アクセスポイント情報のデバッグ表示用関数 +static void DumpWDSApInfo( WDSApInfo *apinfo ); + +// WDS非同期関数のコールバック関数たち +// コールバック関数内ではアプリケーションのステート変数s_appstateを変更する +void WDS_Initialize_CB(void *arg); +void WDS_StartScan_CB(void *arg); +void WDS_EndScan_CB(void *arg); +void WDS_End_CB(void *arg); + +// アプリケーションを制御するステートの列挙型 +typedef enum AppState { + APP_STATE_WDSINIT, + APP_STATE_WDSWAITINIT, + APP_STATE_WDSSCAN, + APP_STATE_WDSWAITSCAN, + APP_STATE_WDSCOMPLETESCAN, + APP_STATE_WDSENDSCAN, + APP_STATE_WDSWAITENDSCAN, + APP_STATE_WDSCOMPLETEENDSCAN, + APP_STATE_WDSWAITEND, + APP_STATE_WDSCOMPLETEEND +} AppState; + + +// 受け取ったビーコン情報を格納する変数(この配列をランチャー経由でホットスポットチャンネルに渡す) +static WDSBriefApInfo briefapinfo[WDS_APINFO_MAX]; + + + +// WDSスキャンスレッドの起動 +void StartScanWDS( void ) +{ + u8 *wdsSysBuf; + + // WDSライブラリが使用するバッファを確保(32バイトアラインメントしている必要がある) + wdsSysBuf = SYSM_Alloc( WDS_GetWorkAreaSize() ); + if( wdsSysBuf == NULL) + { + OS_Panic("OS_Alloc Failed"); + } + // WDSスレッドの起動 + OS_InitMessageQueue( &s_msgQueue, &s_msgBuffer[0], WDS_MESG_DEPTH ); + OS_CreateThread( &s_thread, ScanWDSThread, (void *)wdsSysBuf, s_stack + WDS_STACK_SIZE / sizeof(u64), WDS_STACK_SIZE, WDS_THREAD_PRIO ); + OS_WakeupThreadDirect( &s_thread ); + + (void)OS_SendMessage(&s_msgQueue, (OSMessage)APP_STATE_WDSINIT, OS_MESSAGE_BLOCK ); +} + + +// WDSスキャンスレッド +static void ScanWDSThread( void *arg ) +{ +#pragma unused(arg) + OSTick wdsScanBeginTick = 0; + u8 *wdsSysBuf = arg; + + // メインループ + while( 1 ) { + OSTick now; + int i; + // アプリケーションを制御するステート変数 + AppState appstate; + + (void)OS_ReceiveMessage( &s_msgQueue, (OSMessage)&appstate, OS_MESSAGE_BLOCK ); + + switch( appstate ) + { + case APP_STATE_WDSINIT: + // イニシャルステート + + // WDSライブラリの初期化関数を呼び出し、その非同期処理の完了を待つ + OS_Printf("*** WDS_Initialize\n"); + if( WDS_Initialize( wdsSysBuf, WDS_Initialize_CB, 0 ) == 0 ) + { + OS_Printf("WDS_Initialize successed\n"); + } + else { + OS_Panic("WDS_Initialize failed"); + } + break; + OS_Printf("*** WDS_Initialize waiting asyncronous process\n"); + case APP_STATE_WDSWAITINIT: + case APP_STATE_WDSWAITSCAN: + case APP_STATE_WDSWAITENDSCAN: + case APP_STATE_WDSWAITEND: + // 非同期処理の完了を待つステート群 + + // コールバック関数が呼び出され、ステートが変更されるのを待てばよい + break; + case APP_STATE_WDSSCAN: + // 初期化が完了した直後か、ビーコンスキャン完了時に引き続きスキャンを行う場合に入ってくるステート + + //OS_Printf("*** WDS_StartScan\n"); + // ビーコンスキャン非同期処理を開始する + if( WDS_StartScan( WDS_StartScan_CB ) == 0 ) + { + if( wdsScanBeginTick == 0 ) + wdsScanBeginTick = OS_GetTick(); + } + else { + OS_Panic("WDS_StartScan failed"); + } + break; + case APP_STATE_WDSCOMPLETESCAN: + // スキャン完了後に入ってくるステート + + // 一回のスキャンではビーコンを取れないことが多いので、2秒間ビーコン受信を繰り返す + now = OS_GetTick(); + if( OS_TicksToMilliSeconds(now - wdsScanBeginTick) < 2000 ) + { + // 再スキャンのためにスキャン開始ステートに移行 + (void)OS_SendMessage(&s_msgQueue, (OSMessage)APP_STATE_WDSSCAN, OS_MESSAGE_NOBLOCK ); + } + else { + // スキャン終了ステートに移行 + (void)OS_SendMessage(&s_msgQueue, (OSMessage)APP_STATE_WDSENDSCAN, OS_MESSAGE_NOBLOCK ); + } + break; + case APP_STATE_WDSENDSCAN: + // スキャンを終了させる際に入ってくるステート + OS_Printf("*** WDS_EndScan\n"); + + // スキャンを終了させる非同期処理を開始する + if( WDS_EndScan( WDS_EndScan_CB ) == 0 ) + { + OS_Printf("WDS_EndScan successed\n"); + } + else { + OS_Panic("WDS_EndScan failed"); + } + break; + case APP_STATE_WDSCOMPLETEENDSCAN: + // スキャン終了非同期処理が終わった際に入って来るステート + OS_Printf("*** WDS_GetApInfoAll\n"); + if( WDS_GetApInfoAll( briefapinfo ) != 0 ) + { + OS_Panic("WDS_GetApInfoAll failed\n"); + } + for( i = 0 ; i < WDS_APINFO_MAX ; i++ ) + { + if( briefapinfo[i].isvalid == TRUE ) + { + OS_TPrintf("rssi: %d\n", briefapinfo[i].rssi); + DumpWDSApInfo( &briefapinfo[i].apinfo ); + *(u16 *)0x0500003c = 0x03ff; + } + } + + // WDSライブラリを終了し、無線ハードの電源を落とす非同期処理を開始する + OS_Printf("*** WDS_End\n"); + if( WDS_End( WDS_End_CB ) == 0 ) + { + OS_Printf("WDS_End successed\n"); + } + else { + OS_Panic("WDS_End failed"); + } + break; + case APP_STATE_WDSCOMPLETEEND: + // WDSライブラリの解放処理が完了した際に入って来るステート + SYSM_Free( wdsSysBuf ); + OS_TPrintf("WDS test successfully completed\n"); + return; + } + } +} + +// アクセスポイント情報のデバッグ表示用関数 +static void DumpWDSApInfo( WDSApInfo *apinfo ) +{ + int i; + char buf[256]; + + OS_TPrintf( "================================\n" ); + // SSID + MI_CpuCopy8( apinfo->ssid, buf, WDS_SSID_BUF_SIZE) ; + buf[WDS_SSID_BUF_SIZE] = 0x00; + OS_TPrintf( "SSID: %s\n", buf ); + + // APNUM + MI_CpuCopy8( apinfo->apnum, buf, WDS_APNUM_BUF_SIZE) ; + buf[WDS_APNUM_BUF_SIZE] = 0x00; + OS_TPrintf( "APNUM: %s\n", buf ); + + // CHANNEL + OS_TPrintf( "channel: %d\n", apinfo->channel ); + + // ENCRYPTFLAG + OS_TPrintf( "encryptmethod: %d\n", apinfo->encryptflag); + + // WEPKEY + OS_TPrintf( "WEPKEY: " ); + for( i = 0 ; i < WDS_WEPKEY_BUF_SIZE ; i++ ) + { + OS_TPrintf( "%02x", apinfo->wepkey[i] ); + } + OS_TPrintf( "\n" ); + OS_TPrintf( "================================\n" ); +} + +static void WDS_Initialize_CB(void *arg) +{ +#pragma unused(arg) + OS_TPrintf("WDS_Initialize_CB\n"); + (void)OS_SendMessage(&s_msgQueue, (OSMessage)APP_STATE_WDSSCAN, OS_MESSAGE_NOBLOCK ); +} + +static void WDS_StartScan_CB(void *arg) +{ +#pragma unused(arg) +// OS_TPrintf("WDS_StartScan_CB\n"); + (void)OS_SendMessage(&s_msgQueue, (OSMessage)APP_STATE_WDSCOMPLETESCAN, OS_MESSAGE_NOBLOCK ); +} + +static void WDS_EndScan_CB(void *arg) +{ +#pragma unused(arg) + OS_TPrintf("WDS_EndScan_CB\n"); + (void)OS_SendMessage(&s_msgQueue, (OSMessage)APP_STATE_WDSCOMPLETEENDSCAN, OS_MESSAGE_NOBLOCK ); +} + +static void WDS_End_CB(void *arg) +{ +#pragma unused(arg) + OS_TPrintf("WDS_End_CB\n"); + (void)OS_SendMessage(&s_msgQueue, (OSMessage)APP_STATE_WDSCOMPLETEEND, OS_MESSAGE_NOBLOCK ); +} diff --git a/build/systemMenu_RED/Launcher/ARM9/src/scanWDS.h b/build/systemMenu_RED/Launcher/ARM9/src/scanWDS.h new file mode 100644 index 00000000..5e7f888a --- /dev/null +++ b/build/systemMenu_RED/Launcher/ARM9/src/scanWDS.h @@ -0,0 +1,40 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL + File: scanWDS.h + + Copyright 2007 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef __SCAN_WDS_H__ +#define __SCAN_WDS_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// define data------------------------------------------------------- + +// global variables-------------------------------------------------- + +// function---------------------------------------------------------- +extern void StartScanWDS( void ); + + +#ifdef __cplusplus +} +#endif + +#endif // __SCAN_WDS_H__ diff --git a/build/tests/WDSTest/Makefile b/build/tests/WDSTest/Makefile new file mode 100644 index 00000000..fe71f85b --- /dev/null +++ b/build/tests/WDSTest/Makefile @@ -0,0 +1,40 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlIPL +# File: Makefile +# +# Copyright 2007 Nintendo. All rights reserved. +# +# These coded instructions, statements, and computer programs contain +# proprietary information of Nintendo of America Inc. and/or Nintendo +# Company Ltd., and are protected by Federal copyright law. They may +# not be disclosed to third parties or copied or duplicated in any form, +# in whole or in part, without the prior written consent of Nintendo. +# +# $Date:: $ +# $Rev$ +# $Author$ +#---------------------------------------------------------------------------- + +TARGET_FIRM = SYSTEMMENU +TARGET_PLATFORM = TWL +TWL_ARCHGEN = LIMITED +TWL_PROC = ARM9 + +SRCS = main.c +TARGET_BIN = main.srl + +include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs + +#---------------------------------------------------------------------------- + +LLIBRARIES += WDS$(TWL_LIBSUFFIX).a + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + +#---------------------------------------------------------------------------- +include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules + +#===== End of Makefile ===== diff --git a/build/tests/WDSTest/src/main.c b/build/tests/WDSTest/src/main.c new file mode 100644 index 00000000..17b12e03 --- /dev/null +++ b/build/tests/WDSTest/src/main.c @@ -0,0 +1,297 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL + File: WDS.c + + Copyright 2007 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include +#include + +// ヒープ初期化関数 +static void InitializeAllocateSystem(void); + +// アクセスポイント情報のデバッグ表示用関数 +static void DumpWDSApInfo( WDSApInfo *apinfo ); + +void VBlankIntr(void); + +// WDS非同期関数のコールバック関数たち +// コールバック関数内ではアプリケーションのステート変数g_appstateを変更する +void WDS_Initialize_CB(void *arg); +void WDS_StartScan_CB(void *arg); +void WDS_EndScan_CB(void *arg); +void WDS_End_CB(void *arg); + +// アプリケーションを制御するステートの列挙型 +typedef enum AppState { + APP_STATE_WDSINIT, + APP_STATE_WDSWAITINIT, + APP_STATE_WDSSCAN, + APP_STATE_WDSWAITSCAN, + APP_STATE_WDSCOMPLETESCAN, + APP_STATE_WDSENDSCAN, + APP_STATE_WDSWAITENDSCAN, + APP_STATE_WDSCOMPLETEENDSCAN, + APP_STATE_WDSWAITEND, + APP_STATE_WDSCOMPLETEEND +} AppState; + +// アプリケーションを制御するステート変数 +static AppState g_appstate = APP_STATE_WDSINIT; + +// 受け取ったビーコン情報を格納する変数(この配列をランチャー経由でホットスポットチャンネルに渡す) +static WDSBriefApInfo briefapinfo[WDS_APINFO_MAX]; + +/*---------------------------------------------------------------------------* + Name: NitroMain + + Description: main + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void NitroMain(void) +{ + u8 *wdsSysBuf; + OSTick wdsScanBeginTick = 0; + + // 各種初期化処理 + OS_Init(); + OS_InitTick(); + OS_InitAlarm(); + + //---- interrupt setting + OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr); + OS_EnableIrqMask(OS_IE_V_BLANK); + OS_EnableIrq(); + GX_VBlankIntr(TRUE); + + InitializeAllocateSystem(); + + // WDSライブラリが使用するバッファを確保(32バイトアラインメントしている必要がある) + wdsSysBuf = OS_Alloc( WDS_GetWorkAreaSize() ); + if( wdsSysBuf == NULL) + { + OS_Panic("OS_Alloc Failed"); + } + + // メインループ + while( 1 ) { + OSTick now; + int i; + + OS_WaitVBlankIntr(); + switch( g_appstate ) + { + case APP_STATE_WDSINIT: + // イニシャルステート + + // WDSライブラリの初期化関数を呼び出し、その非同期処理の完了を待つ + OS_Printf("*** WDS_Initialize\n"); + 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"); + } + break; + OS_Printf("*** WDS_Initialize waiting asyncronous process\n"); + case APP_STATE_WDSWAITINIT: + case APP_STATE_WDSWAITSCAN: + case APP_STATE_WDSWAITENDSCAN: + case APP_STATE_WDSWAITEND: + // 非同期処理の完了を待つステート群 + + // コールバック関数が呼び出され、ステートが変更されるのを待てばよい + break; + case APP_STATE_WDSSCAN: + // 初期化が完了した直後か、ビーコンスキャン完了時に引き続きスキャンを行う場合に入ってくるステート + + //OS_Printf("*** WDS_StartScan\n"); + // ビーコンスキャン非同期処理を開始する + 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"); + } + break; + case APP_STATE_WDSCOMPLETESCAN: + // スキャン完了後に入ってくるステート + + // 一回のスキャンではビーコンを取れないことが多いので、2秒間ビーコン受信を繰り返す + now = OS_GetTick(); + if( OS_TicksToMilliSeconds(now - wdsScanBeginTick) < 2000 ) + { + // 再スキャンのためにスキャン開始ステートに移行 + g_appstate = APP_STATE_WDSSCAN; + } + else { + // スキャン終了ステートに移行 + g_appstate = APP_STATE_WDSENDSCAN; + } + break; + case APP_STATE_WDSENDSCAN: + // スキャンを終了させる際に入ってくるステート + OS_Printf("*** WDS_EndScan\n"); + + // スキャンを終了させる非同期処理を開始する + 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"); + } + break; + case APP_STATE_WDSCOMPLETEENDSCAN: + // スキャン終了非同期処理が終わった際に入って来るステート + OS_Printf("*** WDS_GetApInfoAll\n"); + if( WDS_GetApInfoAll( briefapinfo ) != 0 ) + { + OS_Panic("WDS_GetApInfoAll failed\n"); + } + for( i = 0 ; i < WDS_APINFO_MAX ; i++ ) + { + if( briefapinfo[i].isvalid == TRUE ) + { + OS_TPrintf("rssi: %d\n", briefapinfo[i].rssi); + DumpWDSApInfo( &briefapinfo[i].apinfo ); + } + } + + // WDSライブラリを終了し、無線ハードの電源を落とす非同期処理を開始する + OS_Printf("*** WDS_End\n"); + 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"); + } + break; + case APP_STATE_WDSCOMPLETEEND: + // WDSライブラリの解放処理が完了した際に入って来るステート + + OS_TPrintf("WDS test successfully completed\n"); + OS_Terminate(); + } + } +} + +// アクセスポイント情報のデバッグ表示用関数 +static void DumpWDSApInfo( WDSApInfo *apinfo ) +{ + int i; + char buf[256]; + + OS_TPrintf( "================================\n" ); + // SSID + MI_CpuCopy8( apinfo->ssid, buf, WDS_SSID_BUF_SIZE) ; + buf[WDS_SSID_BUF_SIZE] = 0x00; + OS_TPrintf( "SSID: %s\n", buf ); + + // APNUM + MI_CpuCopy8( apinfo->apnum, buf, WDS_APNUM_BUF_SIZE) ; + buf[WDS_APNUM_BUF_SIZE] = 0x00; + OS_TPrintf( "APNUM: %s\n", buf ); + + // CHANNEL + OS_TPrintf( "channel: %d\n", apinfo->channel ); + + // ENCRYPTFLAG + OS_TPrintf( "encryptmethod: %d\n", apinfo->encryptflag); + + // WEPKEY + OS_TPrintf( "WEPKEY: " ); + for( i = 0 ; i < WDS_WEPKEY_BUF_SIZE ; i++ ) + { + OS_TPrintf( "%02x", apinfo->wepkey[i] ); + } + OS_TPrintf( "\n" ); + OS_TPrintf( "================================\n" ); +} + +static void VBlankIntr(void) +{ + OS_SetIrqCheckFlag(OS_IE_V_BLANK); +} + +// ヒープ初期化関数 +static void InitializeAllocateSystem(void) +{ + void *tempLo; + OSHeapHandle hh; + + tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1); + OS_SetArenaLo(OS_ARENA_MAIN, tempLo); + hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi()); + if (hh < 0) + { + OS_Panic("ARM9: Fail to create heap...\n"); + } + hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh); +} + +static void WDS_Initialize_CB(void *arg) +{ +#pragma unused(arg) + OS_TPrintf("WDS_Initialize_CB\n"); + g_appstate = APP_STATE_WDSSCAN; +} + +static void WDS_StartScan_CB(void *arg) +{ +#pragma unused(arg) +// OS_TPrintf("WDS_StartScan_CB\n"); + g_appstate = APP_STATE_WDSCOMPLETESCAN; +} + +static void WDS_EndScan_CB(void *arg) +{ +#pragma unused(arg) + OS_TPrintf("WDS_EndScan_CB\n"); + g_appstate = APP_STATE_WDSCOMPLETEENDSCAN; +} + +static void WDS_End_CB(void *arg) +{ +#pragma unused(arg) + OS_TPrintf("WDS_End_CB\n"); + g_appstate = APP_STATE_WDSCOMPLETEEND; +} diff --git a/include/sysmenu/WDS.h b/include/sysmenu/WDS.h new file mode 100644 index 00000000..addcc443 --- /dev/null +++ b/include/sysmenu/WDS.h @@ -0,0 +1,236 @@ +//********************************************************************** +// +// @file WDS.h +// @brief 店頭親機がMP送信する接続先AP情報を受信 +// +// @author M.Okuno +// @date 2008/02/05 +// @version 01.00 +// +//*********************************************************************/ +#ifndef __WDS_H__ +#define __WDS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//----------------------------------------------------- +// Include +//----------------------------------------------------- +#include + +//----------------------------------------------------- +// Macros +//----------------------------------------------------- +/** + @brief ホットスポット名エンコード情報 +*/ +#define WDS_HOTSPOT_ENCODE_UTF8 0x0000 ///< UTF-8 +#define WDS_HOTSPOT_ENCODE_UTF16 0x1000 ///< UTF-16 +#define WDS_HOTSPOT_ENCODE_MASK 0xF000 ///< マスク + +/** + @brief ホットスポット業者識別 +*/ +#define WDS_HOTSPOT_TYPE_MASK 0x0FFF ///< マスク + +/** + @brief ビーコン内容バッファサイズ +*/ +#define WDS_SSID_BUF_SIZE 32 ///< SSID +#define WDS_APNUM_BUF_SIZE 10 ///< AP番号 +#define WDS_HOTSPOTNAME_BUF_SIZE 24 ///< ホットスポット名 +#define WDS_HOTSPOTNAME_UTF16_BUF_SIZE WDS_HOTSPOTNAME_BUF_SIZE + 2 ///< 変換後のホットスポット名 +#define WDS_MACADDR_BUF_SIZE 6 ///< MACアドレス +#define WDS_WEPKEY_BUF_SIZE 32 ///< WEPキー(あるいはWPA Preshared Key) + +/** + @brief 親機AP情報保持最大数 +*/ +#define WDS_APINFO_MAX 16 + +//----------------------------------------------------- +// Types +//----------------------------------------------------- +/** + @brief WDSライブラリが使用するコールバック関数型 +*/ +typedef void (*WDSCallbackFunc)(void *arg); + +//----------------------------------------------------- +// Structs +//----------------------------------------------------- +/** + @brief 親機から送られてくるAPビーコンの内容 +*/ +typedef struct WDSApInfo +{ + u8 ssid[ WDS_SSID_BUF_SIZE ]; ///< 親機が接続するAPのSSID + u8 apnum[ WDS_APNUM_BUF_SIZE ]; ///< 本来はAPのSSIDに埋め込まれているAP識別番号 + u16 hotspotid; ///< ホットスポットの認証方式を示すフラグ+hotspotnameのエンコード情報 + u8 hotspotname[ WDS_HOTSPOTNAME_BUF_SIZE ]; ///< UTF-8あるいはUTF-16で記述されたホットスポットの名前 + u8 wepkey[ WDS_WEPKEY_BUF_SIZE ]; ///< 親機が接続するAPのWEP キー + u8 channel; ///< 親機が接続したAPが使っているチャンネル + u8 encryptflag; ///< AP接続時にNitroWiFiが使う暗号化方式 + u8 reserve[10]; ///< 予約領域 +} WDSApInfo; + +/** + @brief アプリケーションから閲覧可能なAPビーコンの内容 +*/ +typedef struct WDSBriefApInfo +{ + // WDSライブラリによって生成される値 + BOOL isvalid; + u16 rssi; ///< 電波強度 + + // AP情報ビーコンそのもの + WDSApInfo apinfo; +} WDSBriefApInfo; + +//----------------------------------------------------- +// Prototypes +//----------------------------------------------------- +//-------------------------------------------------------------------------------- +/** WDSライブラリが使用するワークエリアのサイズを得ます + @return 0 以外 : ワークエリアのサイズ + @note + ライブラリ初期化時に使用します +*///------------------------------------------------------------------------------ +size_t WDS_GetWorkAreaSize( void ); + +//-------------------------------------------------------------------------------- +/** WDSを初期化します + @param <1> 呼び出し元によって確保されたバッファへのポインタを指定します + @param <2> 処理が完了した際に呼び出されるコールバック関数へのポインタ + @param <3> WM_InitializeのdmaNoに準ずる引数 + @return 0 : 成功 ( コールバックを待つこと ) + 0 以外 : 失敗 + @note + <1> のサイズはWDS_SYSTEM_BUF_SIZEだけ必要であり、 + かつ 32バイトアラインされている必要があります。 + <2> のコールバックは割り込みハンドラ内から呼び出されます。 + WDS 関連のコールバック関数内では呼び出せません。 + 関数内部でWM_Initialize()を実行する為、WMはREADYステートからIDLEステートに移行します。 +*///------------------------------------------------------------------------------ +int WDS_Initialize( void *wdsWork, WDSCallbackFunc callback, u16 dmaNo ); + +//-------------------------------------------------------------------------------- +/** WDSを初期化します(指定したスキャン結果を内部的に保持した状態での初期化) + @param <1> 呼び出し元によって確保されたバッファへのポインタを指定します + @param <2> 処理が完了した際に呼び出されるコールバック関数へのポインタ + @param <3> WM_InitializeのdmaNoに準ずる引数 + @param <4> 事前にWDSを使用して取得したWDSBriefInfoの配列 + @return 0 : 成功 ( コールバックを待つこと ) + 0 以外 : 失敗 + @note + <1> のサイズはWDS_SYSTEM_BUF_SIZEだけ必要であり、 + かつ 32バイトアラインされている必要があります。 + <2> のコールバックは割り込みハンドラ内から呼び出されます。 + WDS 関連のコールバック関数内では呼び出せません。 + 関数内部でWM_Initialize()を実行する為、WMはREADYステートからIDLEステートに移行します。 +*///------------------------------------------------------------------------------ +int WDS_InitializeEx( void *wdsWork, WDSCallbackFunc callback, u16 dmaNo, WDSBriefApInfo *apinfo ); + +//-------------------------------------------------------------------------------- +/** WDSを終了します + @param <1> 処理が完了した際に呼び出されるコールバック関数へのポインタ + @return 0 : 成功 ( コールバックを待つこと ) + 0 以外 : 失敗 + @note + <1> のコールバックは割り込みハンドラ内から呼び出されます。 + WDS 関連のコールバック関数内では呼び出せません。 +*///------------------------------------------------------------------------------ +int WDS_End( WDSCallbackFunc callback ); + +//-------------------------------------------------------------------------------- +/** DS配信システム親機ビーコンのスキャンを開始します + @param <1> 処理が完了した際に呼び出されるコールバック関数へのポインタ + @return 0 : 成功 ( コールバックを待つこと ) + 0 以外 : 失敗 + @note + <1> のコールバックは割り込みハンドラ内から呼び出されます。 + WDS 関連のコールバック関数内では呼び出せません。 + 関数内部でWM_StartScane()を実行する為、WMはIDLEステートの場合はSCANステートに移行します。 +*///------------------------------------------------------------------------------ +int WDS_StartScan( WDSCallbackFunc callback ); + +//-------------------------------------------------------------------------------- +/** DS配信システム親機ビーコンのスキャンを終了します + @param <1> 処理が完了した際に呼び出されるコールバック関数へのポインタ + @return 0 : 成功 ( コールバックを待つこと ) + 0 以外 : 失敗 + @note + <1> のコールバックは割り込みハンドラ内から呼び出されます。 + WDS 関連のコールバック関数内では呼び出せません。 + 関数内部でWM_EndScan()を実行する為、WMはIDLEステートに移行します。 +*///------------------------------------------------------------------------------ +int WDS_EndScan( WDSCallbackFunc callback ); + +//-------------------------------------------------------------------------------- +/** APビーコン情報の数を取得します + @return 0 以上 : 成功 + 0 未満 : 失敗 ( スキャン中 ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_GetApInfoNum( void ); + +//-------------------------------------------------------------------------------- +/** APビーコン情報をインデックスを指定して取得します + @param <1> 取得するAPビーコン情報のインデックス値(0〜15) + @param <2> 取得するAPビーコン情報を書き込む領域へのポインタ + @return 0 : 成功 + 0 以外 : 失敗 ( スキャン中、又はインデックスの示す位置にデータがない ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_GetApInfoByIndex( int index, WDSBriefApInfo *briefapinfo ); + +//-------------------------------------------------------------------------------- +/** APビーコン情報を全て取得します + @param <1> 取得するAPビーコン情報を書き込む配列の先頭へのポインタ(WDS_APINFO_MAX個の要素が必要) + @return 0 : 成功 + 0 以外 : 失敗 ( スキャン中、又はインデックスの示す位置にデータがない ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_GetApInfoAll( WDSBriefApInfo *briefapinfo ); + +//-------------------------------------------------------------------------------- +/** APビーコン情報をDWCの自動接続先として設定します + @param <1> 自動接続先として設定するAPビーコン情報のインデックス値(0〜15) + @return 0 : 成功 + 0 以外 : 失敗 ( スキャン中、又はインデックスの示す位置にデータがない ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_SetConnectTargetByIndex( int index ); + +//-------------------------------------------------------------------------------- +/** APビーコン情報をDWCの自動接続先として設定します + @param <1> 自動接続先として設定するAPビーコン情報 + @return 0 : 成功 + 0 以外 : 失敗 ( スキャン中、又はインデックスの示す位置にデータがない ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_SetConnectTargetByBriefApInfo( WDSBriefApInfo *briefapinfo ); + +//-------------------------------------------------------------------------------- +/** APビーコン情報のAP説明文をUTF-16で得ます + @param <1> AP説明文を取得する対象のAPビーコン情報 + <2> AP説明文を書き込むバッファへのポインタ(WDS_HOTSPOTNAME_UTF16_BUF_SIZEバイト) + @return 0 : 成功 + 0 以外 : 失敗 ( スキャン中、又はインデックスの示す位置にデータがない ) + @note + スキャン中に実行した場合はエラー値を返します。 +*///------------------------------------------------------------------------------ +int WDS_GetApDescriptionUTF16( WDSBriefApInfo *briefapinfo, void *outbuf ); + +#ifdef __cplusplus +} +#endif + +#endif //EOF __WDS_H__