インターネット同時接続モードの設定

本チュートリアルでは、RaspberryPi上でiSDIOドライバAPIを使用してFlashAirを制御し、 インターネット同時接続モードの設定を行います。


サンプル環境

HW:Raspberry Pi 3 Model B + microSD->SD変換アダプタ OS:Raspbian (NOOBS ver.2.4.3) NW:インターネット接続が可能なアクセスポイント

サンプル環境

microSD変換アダプタを使用してRaspberry Pi 3のmicroSDスロットにFlashAirを上図のように接続します。


サンプルコード実行手順

  1. 事前準備としてFlashAirからRaspberryPiを起動できるよう準備します。
    また、SD_WLANフォルダのCONFIGファイルにAPPMODE=0を記載してください。
  2. こちらよりサンプルコード環境をダウンロードして、RaspberryPi上に展開します。
    展開場所はどこでも構いません。
  3. 展開すると下記のような構成で展開されますので、ターミナルからsampleフォルダまで移動します。

    iSDIO_tutorial_sample
    |-incフォルダ(iSDIOドライバAPI ヘッダ部)
    |  |- isdio_api.h
    |  |- isdio_wlan_api.h
    |  |- isdioreg.h
    |  └─ mmc.h
    |
    |-sampleフォルダ
    |  |- iSDIO_tutorial_sample.c (本チュートリアルサンプルコード)
    |  └─ Makefile
    |
    └─srcフォルダ(iSDIOドライバAPI ソース部)
      |- isdio_api.c
      |- isdio_wlan_api.c
      └─ isdioreg.c
    
  4. ターミナル上でmakeを実行します。meke成功でsampleフォルダ内に実行ファイルisdio_sampleが作成されます。
    ただし、インターネットに接続するアクセスポイント名、パスワードは環境によって違いますので、こちらを参照して変更してください。
  5. 4.で作成されたisdio_sampleを実行します。
    ただし、iSDIOドライバを使用するには管理者権限が必要となります。下記のように実行してください。

    > sudo ./isdio_sample
    

ダウンロードしたサンプルコード(iSDIO_tutorial_sample.c)を解説していきます。

iSDIOドライバの初期化

FlashAirを使用するためiSDIOカード制御情報の初期化を行います。

iSDIO_tutorial_sample.c(一部参照)
    iSDIO_INFO_t *s_info;                                   /* iSDIOカード制御情報ポインタ */
    char *s_device = "/dev/mmcblk0" ;                       /* SDカードデバイス情報 */

    /* iSDIO初期化 */
    s_info = iSDIO_Init(s_device);  
    printf(" info=0x%p\n", s_info);
    if (s_info != NULL) {
      printf("info->fno=%d\n", s_info->fno);
      system("mount /dev/mmcblk0p1 /mnt");
  • 33行目
    iSDIOカード制御情報の先頭アドレスを取得するためのポインタを準備します。
    iSDIOカード制御情報はiSDIO_Initの戻り値として取得し、各コマンドおよびレスポンスでハンドラとして使用します。
  • 34行目
    SDカードデバイス情報はFlashAirのデバイス情報が設定されるため環境によって変更してください。
  • 53行目
    FlashAirをmountするため、環境によって変更してください。

アクセスポイントの検索

FlashAirが認識できるアクセスポイントの検索を行います。

iSDIO_tutorial_sample.c(一部参照)
    /* 周りのアクセスポイントの情報を取得 */
    result = iSDIO_WLAN_Scan(s_info, s_seq_id ++);

    if (result == E_iSDIO_OK) {
      /* iSDIOコマンド実行プロセスの完了を待つ */
      timeout = 20000;          /* Scanのタイムアウトは20秒なので、20000ms */
      cmd_success = FALSE;
      /* WLAN_Scanレスポンス待ち */
      cmd_success = response_wait(s_info, (s_seq_id-1), iSDIO_WLAN_SCAN, timeout);

      if (cmd_success == FALSE) {
        printf("WLAN_Scan response error !!!\n");
      }
      else {
  • 55行目
    iSDIO_WLAN_Scanは非同期関数のため62行目でのレスポンス待ちが必要となります。
    55行目のレスポンスはiSDIO_WLAN_Scanコマンド実行の成否となり、62行目のレスポンス待ちはiSDIO_WLAN_Scanコマンド実行結果の成否となります。
    コマンド・レスポンスについてはこちらを参照。
    また、引数のシーケンスIDは新しくコマンドを発行するたびにユニークな値を設定します。
    そのため、シーケンスID使用後インクリメントを行っています。
  • 62行目
    レスポンスデータ取得時には、コマンドIDとシーケンスIDでどのコマンド実行時のレスポンスかを判断します。
    そのため、iSDIO_WLAN_Scanコマンド実行時のシーケンスIDを設定するため現在のシーケンスIDから-1した値でレスポンス待ちを行っています。

インターネット同時接続モードの設定

FlashAirを使用してインターネット接続をしながら自身をアクセスポイントに設定します。

iSDIO_tutorial_sample.c(一部参照)
    uint8_t apssid[32]          = "myflashair";               /* FlashAir(AP側) 無線LAN SSID */
    uint8_t apnetworkKey[64]    = "password0123";             /* FlashAir(AP側) 無線LAN ネットワークキー */
    uint8_t brgssid[32]         = "LANSSID";                  /* インターネット(STA側) 無線LAN SSID */
    uint8_t brgnetworkKey[64]   = "lanpassword0123";          /* インターネット(STA側) 無線LAN ネットワークキー */
    uint32_t encMode            = iSDIO_WLAN_ENCMODE_WPA2_PSK_AND_AES;  /* 動作モード=6 */

            /* 周りにアクセスポイントがある場合 */
            /* アクセスポイント名を取得して対象のSTAがあるか判別 */
            for(lp=0;lp<num;lp++) {
              memset(getssid,0x00,32);            /* アクセスポイント名取得用バッファクリア */
              /* 指定番号のアクセスポイント名を取得 */
              result = iSDIO_WLAN_GetSSID(s_info, lp , getssid);
              if(result != E_iSDIO_OK) {
                printf("WLAN_GetSSID get error !!!\n");
                exit(0);
              }
              printf("SSID#%d SSID=%s\n",lp, getssid);
              if(strstr((const char *)getssid, (const char *)brgssid)) {
                /* 対象のSTAありでBridge設定*/
                result = iSDIO_WLAN_Bridge(s_info, s_seq_id++,
                            apssid, sizeof(apssid),
                            apnetworkKey, sizeof(apnetworkKey),
                            encMode,
                            brgssid, sizeof(brgssid),
                            brgnetworkKey, sizeof(brgnetworkKey));
                if(result != E_iSDIO_OK) {
                    printf("Bridge Set error!!!\n");
                    exit(0);
                }
                break;
              }
            }
  • 93行目
    FlashAir自身がアクセスポイントとなるためのSSIDとそのレングス長を設定します。
  • 94行目
    アクセスポイントのネットワークキーとそのレングス長を設定します。
  • 95行目
    アクセスポイントの動作モードを設定します。インターネット同時接続モード場合は動作モード=6固定となります。
  • 96行目
    インターネットと接続しているステーション側のSSIDとそのレングス長を設定します。
  • 97行目
    インターネットと接続しているステーション側のネットワークキーとそのレングス長を設定します。

注意点 iSDIO_WLAN_BridgeはFlashAirがDisconnect状態でないと機能しません。
FlashAirがすでに別の機器接続状態の場合は、まずはiSDIO_WLAN_Disconnectを実行してください。
接続状態を知りたい場合は、iSDIO_WLAN_Check_WLANConnectを実行すると、引数connectに接続状態が出力されます。

レスポンス待ち処理

非同期コマンドの結果を待つ、レスポンス待ち処理について説明しておきます。

iSDIO_tutorial_sample.c(一部参照)
    /* コマンドレスポンス待ちサンプル関数 */
    bool_t response_wait(iSDIO_INFO_t *s_info, uint32_t seq_id, uint32_t cmd_id, int32_t timeout)
    {
      iSDIO_CommandResponseStatus_t *status;
      int32_t timeout_cnt = timeout / 10;    // ms / 10
      bool_t cmd_success = FALSE;

      /* コマンドレスポンスステータスが実行中から抜けるかタイムアウトするまでループする */
      do {
        status = iSDIO_ReadCommandResponseStatus(s_info);
        if ((status->response_status != iSDIO_COMMAND_PROCESSING) && (status->cmd_id==cmd_id)) {
          if (status->response_status == iSDIO_PROCESS_SUCCEEDED) {
            cmd_success = TRUE;
          }
          break;
          printf("res_wait=%d\n",status->response_status);
        }
        sleep(10);    // 10ms待つ
        timeout_cnt --;
      } while (timeout_cnt > 0);
      return cmd_success;
    }
  • 160行目
    FlashAirのレジスタ情報Command Response Statusを読み出す内部関数。
    コマンドのレスポンスステータスを取得します。
  • 161行目
    レスポンスステータスが処理中ではなく、実施したコマンドのレスポンスであるならレスポンス正常でレスポンス待ちを抜け、戻り値にTRUEを返しています。
  • 168-170行目
    レスポンスステータスがまだ処理中の場合のタイムアウト処理。
    このサンプルでは10ms単位でレスポンスステータスの確認を行い、引数のtimeout時間分レスポンス待ちを行っています。
    タイムアウトの場合は戻り値にFALSEを返しています。

実行結果

実行してみましょう。

> sudo ./isdio_sample
dev/mmcblk0 open success
info=0x27268
info->fno=1
SSID#1 SSID=LANSSID
WLAN_Bridge set success
WLAN_BridgeGetInfoByRegister get response success
  • 2-4行目
    FlashAirを正常に認識した場合のみ成功のログ表示とFlashAirのデバイスハンドルIDが表示されます。
  • 5行目
    SSIDが見つかった順番とアクセスポイント名は該当のアクセスポイントが見つかるか、Scanで発見されたアクセスポイント数分表示されます。
    最後に表示されたものが該当のアクセスポイントとなります。
    発見できなかった場合はエラーログが表示されます。
  • 6行目
    インターネット同時接続モードの設定が成功した場合のみ成功のログ表示がされます。
    接続失敗の場合はエラーログが表示されます。
  • 7行目
    ブリッジ情報の取得が成功した場合のみ成功のログ表示がされます。
    インターネットにつながっていないPC・スマートフォンなどから「myflashair」というSSIDに繋ぎ、http://flashair/にアクセスできることを確認してください。
    また、インターネットに接続できることを確認してください。
    情報取得失敗の場合はエラーログが表示されます。

コマンド・レスポンスについて

非同期となるコマンドは下記となります。

  • iSDIO_WLAN_Scan
  • iSDIO_WLAN_Connect
  • iSDIO_WLAN_Establish
  • iSDIO_WLAN_WiFiDirect
  • iSDIO_WLAN_StartWPS
  • iSDIO_WLAN_StartWPSAP
  • iSDIO_WLAN_Disconnect
  • iSDIO_WLAN_SetCurrentTime
  • iSDIO_WLAN_Abort
  • iSDIO_WLAN_ReadResponse
  • iSDIO_WLAN_SetPowerSaveMode
  • iSDIO_WLAN_SetCannel
  • iSDIO_WLAN_SendHTTPMessageByRegister
  • iSDIO_WLAN_SendHTTPFileByRegister
  • iSDIO_WLAN_SendHTTPSSLMessageByRegister
  • iSDIO_WLAN_SendHTTPSSLFileByRegister
  • iSDIO_WLAN_SendHTTPMessageByFile
  • iSDIO_WLAN_SendHTTPFileByFile
  • iSDIO_WLAN_SendHTTPSSLMessageByFile
  • iSDIO_WLAN_SendHTTPSSLFileByFile
  • iSDIO_WLAN_Request
  • iSDIO_WLAN_SetCertificate
  • iSDIO_WLAN_SetCertificateByFile
  • iSDIO_WLAN_StartP2PSender
  • iSDIO_WLAN_StartP2PReceiver
  • iSDIO_WLAN_GetFile
  • iSDIO_WLAN_ReadIDList
  • iSDIO_WLAN_SelectMAC
  • iSDIO_WLAN_DeselectMAC
  • iSDIO_WLAN_SetID
  • iSDIO_WLAN_Bridge
  • iSDIO_WLAN_BridgeGetByRegister

同期となるコマンドは下記となります。

  • iSDIO_Init
  • iSDIO_WLAN_WriteSharedMemory
  • iSDIO_WLAN_ReadSharedMemory
  • iSDIO_WLAN_GetFlashAirVersion
  • iSDIO_WLAN_GetSSIDs
  • iSDIO_WLAN_GetSSID
  • iSDIO_WLAN_GetStatusData
  • iSDIO_WLAN_GetResponseData
  • iSDIO_WLAN_GetVersion
  • iSDIO_WLAN_SetWaitResponseTime
  • iSDIO_WLAN_Check_WLANConnect
  • iSDIO_WLAN_Check_WLAN
  • iSDIO_WLAN_Get_WLAN_Status

サンプルコード環境一式

iSDIO_tutorial_sample.zip (24KB)