環境
- カメラ付きのESP32
- 利用した無料ホームページサービス fc2
- Windows 10
- Arduino IDE ver. 1.8.13
- Arduinoのライブラリマネージャで esp32_ftpclient ver.0.1.1 をインストール
- debugに利用 wireshark, ffftp
やりたいこと
ESP32に繋いだカメラの画像をライブカメラとしてホームページにアップする。ftpでアップロードする
かなり参考になるサンプルソース
ldab/ESP32-CAM-Picture-Sharing
色んな処理が入ってるので、もっとシンプルにしました。
具体的には、ループで 単にカメラから取得したjpg画像をアップロードし続けるだけにしました。
困ったこと
以下のようなエラーが出て、ファイルをアップできないことがありました。
Send PASV
Data port: 64359
Send STOR
FTP error: Offline
Write File
FTP error: Offline
で、暫く続けていると、アップロードできることもありました。
その時のシリアルモニタは以下のように表示されます。
Send TYPE
Type I
Send PASV
Data port: 64359
Data connection established
Send STOR
Writing
Close File
Connection closed
Windows desktop appのffftpだと ほぼ毎回うまくアップロード出来ていました。
esp32 ftpclientのソースコードと、シリアルモニタログを見比べて、PASVコマンドに対するftpサーバからのレスポンスを受信後、レスポンスで指定されたPASVポートに対して接続しにいって、接続できていないことが分かりました。
ffftpで正常時のwiresharkログと、esp32 ftpclientのソースコードでPASVコマンド発行後の処理を見比べて 以下のことが分かりました。
- PASVに対するレスポンスではポート番号だけではなく、IPアドレスも設定されている。
- そのIPアドレスはftpサーバと異なることがある
- esp32 ftpclientでは、レスポンスのIPアドレスフィールドを参照しておらず、PASVポート番号のみ参照し、ftpサーバのPASVポート番号に接続しにいってる
- アップロードが成功したケースでは、PASVレスポンス内のIPアドレスが たまたま ftpサーバと同一だった。
対策
で、以下のようにPASVモードの処理を修正し、正常にftpサーバにアップロードできるようになりました。
(中略)
void ESP32_FTPClient::InitFile(const char* type){
(中略)
//added
IPAddress pasvServer(array_pasv[0],array_pasv[1],array_pasv[2],array_pasv[3]);
//added
FTPdbg(F("Data port: "));
hiPort = hiPort | loPort;
FTPdbgn(hiPort);
//modified
//if (dclient.connect(serverAdress, hiPort, timeout)) {
if (dclient.connect(pasvServer, hiPort, timeout)) {
FTPdbgn(F("Data connection established"));
}
(以下略)
その他
- esp32 ftpclientのlibrary以外も含めたソースコードは後日、GitHubにアップするかもしれません。
- esp32 ftpclientのgit hubにissueとして登録しました。 →(後日談)→ ownerのldabさんから。「fc2のサーバーで試してみたら 同じIPアドレスが返ってきたから PASV responseのIPアドレスをparseする必要なし」の意味の回答あり。対応してくれなさそうなので、私自身の GitHubで修正版を公開予定です。→(後日談)→ forkして修正版をあげたんですが、その後、ldabさんが対応してくれたので、私のほうの修正版は削除しました。おしまい。