Pages

2015年8月28日

ESP8266のSSL clientについて

ESP-WROOM-02でhttpsなAPIを叩こうとしたらハマったので、まとめておきます。

SDKは1.3.0 (Release date: Aug 08, 2015)を使用しています。
ドキュメントも、これ(esp_iot_sdk_v1.3.0_15_08_08.zip)に含まれている2C-ESP8266__SDK__Programming Guide__EN_v1.3.0.pdfを参照しました。

現状

8/28現在、Arduino core for ESP8266はSSL(TLS)でのclientに対応していない。
対応して欲しいという要望&対応したいねという話は出ている。

ESP8266のSDKとしては、SSLに対応している。
※ただし、制約あり(この下に書きます)

処理の流れ

公式によるサンプルコードがEspressifのフォーラムにあるので、それを見るとだいたい分かります。

以下も非常に参考になります。
DSAS開発者の部屋:ESP8266 モジュールの AT コマンドに SSL クライアント機能を追加する
ESP-WROOM-02で、IFTTTをhttps(SSL/TLS)で呼び出す例 - Qiita

大雑把な流れとしては...

//証明書ストアを用意
unsigned char *default_certificate;
unsigned int default_certificate_len = 0;
unsigned char *default_private_key;
unsigned int default_private_key_len = 0;

//espconn, _esp_tcpを定義

LOCAL struct espconn user_tcp_conn;
LOCAL struct _esp_tcp user_tcp;

//接続先のIPアドレスとポートを設定
user_tcp.remote_ip[0] = 192;
user_tcp.remote_ip[1] = 168;
user_tcp.remote_ip[2] = 1;
user_tcp.remote_ip[3] = 128;
user_tcp.remote_port = 443;

//自分のポートを設定
user_tcp.local_port = espconn_port();

//type, state等を設定
user_tcp_conn.proto.tcp = &user_tcp;
user_tcp_conn.type = ESPCONN_TCP;
user_tcp_conn.state = ESPCONN_NONE;

//接続時、再接続時、接続断時のコールバックを設定
espconn_regist_connectcb(&user_tcp_conn, user_tcp_connect_cb);
espconn_regist_reconcb(&user_tcp_conn, user_tcp_recon_cb);
espconn_regist_disconcb(&user_tcp_conn, user_tcp_discon_cb);

//SSLバッファサイズを設定
espconn_secure_set_size(ESPCONN_CLIENT,5120);

//接続する
espconn_secure_connect(&user_tcp_conn);

みたいな感じ?

user_tcp_connect_cb()関数の中でデータ送受信時のコールバックを設定してあげれば良いみたい。

void user_tcp_connect_cb() {
    espconn_regist_recvcb(pespconn, user_tcp_recv_cb);
    espconn_regist_sentcb(pespconn, user_tcp_sent_cb);
}

サーバからの応答は
void user_tcp_recv_cb(void *arg, char *pusrdata, unsigned short length)
のpusrdataに入ってくるので、これを出力するなり判定するなりすると良い。

SSLバッファサイズはデフォルト(espconn_secure_set_sizeを呼ばない場合)で2048バイトになっているので、SSLパケットが2048バイトを超えそうな時は適宜増やしてね、ということらしい。
最大8192バイトらしいけど、8192を設定したらメモリに乗り切れないっぽくて(確保できない?)、espconn_secure_connectの段階でこけました。
公式サンプルコードにあるように5120くらいが限界かな...?

使用できるプロトコル(バージョン)と暗号

たぶん、ここが一番重要で、メモリ周りとかは全然大丈夫だけどespconn_secure_connectした直後にuser_tcp_discon_cbが呼ばれる(接続断される)ような、とあるサービスのAPIサーバがあって、Wiresharkでパケットキャプチャしたら原因が分かりました。

こちらがESP8266からサーバに送信されたClient Hello。


バージョンはTLS 1.1で、Cipher Suitesは以下の4種。

  • TLS_RSA_WITH_AES_128_CBC_SHA
  • TLS_RSA_WITH_AES_256_CBC_SHA
  • TLS_RSA_WITH_RC4_128_SHA
  • TLS_RSA_WITH_RC4_128_MD5


TLS 1.1を拒否ってたり、上記暗号種での接続を拒否ってると


「お前の指定したバージョン、暗号種ではうちに繋げねーぞ」とHandshake Failureが返ってきてServer Helloしてくれない訳です。

HeartbleedとかPOODLEとか色々あった関係で、厳しめなところは繋がらないという感じかなぁ。

このマイコンの性能上、強度の高い暗号アルゴリズムは載せられないのでしょうが、IoT向けを前面に押し出してるからには、もうちょっと頑張ってほしい...

追記その後、Arduino core for ESP8266でWiFiClientSecureが追加され、httpsが叩けるようになりました。

2015年8月26日

ESP-WROOM-02でIoTデバイスっぽいものを作る(1)


前回(ESP-WROOM-02を使ってみる)の続き。

サンプルを漁ってたらCaptive Portalを使ったものがあったので、早速この機能を使って何か作ることに。
Captive Portal = APに接続したら強制的にWebページ(普通は認証ページなど)を開かせる、公衆無線LANに良くあるアレです。
そして、
1. ESP-WROOM-02をアクセスポイントにできる
2. Captive Portalが使える
3. ESP-WROOM-02がクライアントになれる
ということは...
スマホだけで家のアクセスポイントへの接続設定が出来るIoTデバイスを作れる訳です。

想定
1. 利用者がIoTデバイスの電源を入れる
2. 取説に書いてある特定のSSIDのAPが出現するので、それにスマホで接続する
3. 設定ページが自動的に立ち上がる
4. 家に既設のAPを選択し、パスワードを入力して設定
5. 自動的に再起動して、今度はクライアントとして家のLANにぶら下がってくれる

こういう物が出来れば素敵... というわけで、まずは雛形として使えそうなものを作ってみました。

9SQ/esp8266-wifi-setup (GitHub)

Arduino core for ESP8266を使っているので、前回の記事でも書いたようにArduino IDEへのボード情報の設定が必要です。

実際のスマホでの設定画面はこんな感じ。


その時のシリアルモニタはこんな感じ。


動作としては、
1. EEPROMを読みに行って、設定が存在しない場合はSetup Modeになる
2. 一旦、STA modeで周辺のアクセスポイントを検索して保存
3. AP modeに切り替えて、設定されたSSIDでアクセスポイントを立てる
4. WebサーバとDNSサーバも立てる
5. 接続してきたクライアントはCaptive Portalで設定ページに飛ばす
6. 設定ページから入力されたSSIDとパスワードをURLデコード
7. EEPROMに書き込み
8. 再起動
9. EEPROMを読みに行って、設定されたSSIDのAPに接続する
10. 接続を確立したらWebサーバを立てる
という流れです。

・設定したSSIDのAPに接続できなかったら、再びSetup Modeになります。
・設定後にシリアルモニタに出力されるIPアドレスに接続するとWebサーバが立ち上がってますが、ここにアクセスすると接続設定のリセットが可能です。

あとは、これにセンサーなどを接続してあげれば、同一LAN内からブラウザで値を覗いたり、外部のサーバにデータを定期的に送るようなデバイスが作れると思います。

実はまだ手を入れるところ(接続確立後に何らかの問題で接続断したときの再接続処理など)が結構残っているので、ぼちぼち修正する予定...と並行して次回は実際に何か作ってみたものを載せようと思います。

2015年8月25日

ESP-WROOM-02を使ってみる


たいへん出遅れました!
今更ながらESP-WROOM-02をゲットできたので、先人の日本語による資料の恩恵を受けながら、サクッと使ってみます。

ちなみに、aitendoで買いました。2個パックが1100円(税別)。
秋月電子だとbreakout boardが売って無くてつらいのですが、aitendoだと1個120円で売ってます。
スイッチサイエンスだとモジュールが1個あたり864円、ピッチ変換が162円なので、たぶんネットで買える店の中ではaitendoが最安っぽいです。10個以上買うと秋月の方が安くなりますが。(2015年8月25日現在)
#スイッチサイエンスさんは学校とかで買いやすいので、研究などで買うときは使ってます。

aitendo
Wi-Fiモジュール(技適マック付き/2PCS) [ESP-WROOM-02P] 1100円(税別)
WiFiモジュール変換基板(A) [IFB1518-A] 120円(税別)
WiFiモジュール変換基板(B) [IFB1518-B] 120円(税別)

秋月電子通商
Wi-Fiモジュール ESP-WROOM-02 [ESP-WROOM-02] 550円(税込)

スイッチサイエンス
ESP-WROOM-02 Wi-Fiモジュール 864円(税込)
ESP-WROOM-02ピッチ変換済みモジュール《フル版》 ボードのみ 162円(税込)
ESP-WROOM-02ピッチ変換済みモジュール《シンプル版》 ボードのみ 162円(税込)

さて、注文して届いたモジュールをbreakout board(ピッチ変換基板)にハンダ付けします。
今回はaitendoの変換基板(A)と(B)を1個ずつ買ったので、どっちも付けて比較。
温調ハンダごてだと引きハンダで綺麗に付けやすい。


ブレッドボードに刺すときは2枚を跨がせるか、基板の下をジャンパワイヤーで配線すれば良し。


上の写真では、LED(GPIO4)と気圧センサーLPS25H(SDA=GPIO12, SCL=GPIO14)を接続しています。
ボタンの青がRST、黄色がGPIO0に繋がっているので、黄色を押しながら青を押すとUART Download Modeに入ります。

あとは、先人たちの資料を読みながら、今回はArduino IDEでプログラムを書いていきます。

ググれば色々出てきますが、この辺りが参考になりました。
「ESP-WROOM-02」をArduinoで開発 - おかゆ日和
ESP8266 - ESP-WROOM-02 の Arduino 環境で I2C 制御 - Qiita
ねむいさんのぶろぐ | 技適マーク付きESP8266モジュール ESP-WROOM-02 を使ってみる

LEDのON/OFFをブラウザから操作するのは、サンプルのESP8266WiFi → WiFiWebServerで実現できました。
気圧計は、通常のArduino向けに書かれたコードと、WiFiWebServerを組み合わせて簡単に作れます。

気圧計LPS25HをArduinoで読み取るコードは以下が使えると思います。
Arduinoで遊ぶページ | 大気圧・温度センサモジュールの実験

Raspberry Piで読み取るコードを以前Pythonで書いていたので、これも処理の流れの参考にできるかな。
9SQ/raspi_lps25h.py | Raspberry PiとLPS25Hで気圧取得

ちなみに、I2CはSCLをGPIO14にすればSDAはどのピンでも良いみたいです。
上記Qiita投稿ではSDAをGPIO4に繋げてるみたいですが、私はGPIO12でも動きました。
データシートではGPIO2がSDAになってるんですが、ここは起動時にプルアップしないといけないので、使わなくていいなら使わない方が楽。

GPIOについては、4, 5, 12, 13, 14, 16が使えるよーっという投稿をどこかで見かけた気がしますが、実際には0, 2, 15, 1(U0TXD), 3(U0RXD)も使えます。
ただし、これらのピンは起動時、プログラミング時に使用するピンなので使う際は工夫が必要です。

というわけで、そういうのを踏まえてESP-WROOM-02用のPINOUT DIAGRAMを作ってみました。

PDF版ダウンロード (893KB)

修正ポイントがあったら、記事へのコメントなどで教えてください。
ライセンスはCC0です。(いろんな所で使いやすいように)
著者表記・バックリンク不要ですが、してくれたらそれはそれで嬉しいのでお好みでどうぞ。
※PDFへの直リンクはダメです。

続き→ ESP-WROOM-02でIoTデバイスっぽいものを作る(1)
続き2→ ESP8266のSSL clientについて
続き3→ ESP-WROOM-02でYoを送るボタンを作ってみた

2015年8月23日

Triple.fi 10viのプラグを修理

買ってから5年くらい経つUltimate EarsのTriple.fi 10vi、今までに買った純正ケーブルは2本。
そのうち最初の1本はプラグの根元が2年前に断線して、新しいケーブルを買ったので保管していました。
そしてつい先日、新しい方のケーブルも右耳側が断線、新しいケーブルを再び注文しようと思ったら、もうロジクールストアで扱ってないという...

というわけで、2本のうち修理しやすいプラグ側が断線したケーブルを修理することに。
使ったのはオヤイデ電気のP-3.5/4Gというプラグ。
色々探したけど、ネットで買える自作用の4極プラグがこれくらいしか見当たらなかった。
(ebayや中国とかからの輸入を除く)


1000円くらいしました。純金メッキらしいです。
#オーディオオタクではないので、普通に「高い」と感じる...

Triple.fi 10viのケーブルはCTIA配線なので、オヤイデのWebサイトに載っているCTIAの結線図で付けます。


線の色と対応は上の写真の通り。


無事復活。
一般人なので「高音の伸びが〜」とかは分かりませんでした。おわり。