【解決】Arduino-ESP32 1.0.1 の BLEClient の connect が1.0.0のコードと同じだと無限待機する件

#概要
1.0.0 では大丈夫だったコードでなぜか 1.0.1 だとうまく動かないコードがあって、調べてみたところ
既に伝わってる問題のようであるのだけど、まぁ解決してない(当初執筆時現在)

https://github.com/nkolban/esp32-snippets/issues/744
https://github.com/nkolban/esp32-snippets/issues/767

以下は夢は人に託すなと歌の歌詞にあったので自分の足で歩こうとするおっさんの話。

#なお
2019/2/3 現在、[767](https://github.com/nkolban/esp32-snippets/issues/767) のほうに wakwak-koba さんや chegewara さんのコメントにあるとおり「connect 呼ぶときはアドレスとタイプを指定する関数ならタイプまでちゃんと指定する」「もしくは BLEAdvertisedDevice* を渡すほうの関数を使う」で解決するっぽいです。以下は経緯とかなんとかのために残しておきますが、これを知ってれば読まなくて大丈夫！


#問題点
元々 `BLEClient::connect` 関数の中で `m_semaphoreOpenEvt.wait("connect"); ` している奴に give するパートが、
`void BLEClient::gattClientEventHandler` 関数の `swicth` での `case ESP_GATTC_OPEN_EVT:` のところなのだが、
たまに `ESP_GATTC_OPEN_EVT` が来てないのに切断されて `ESP_GATTC_DISCONNECT_EVT:` が来てしまい、
結果前述の`m_semaphoreOpenEvt.wait("connect"); `が永遠に待機状態になる、

というもの。

#弄ってみよう
`ESP_GATTC_OPEN_EVT:` が来た時は `m_isConnected = true;` に設定してから、`give` するので、
要するに `m_isConnected == false` な時に `ESP_GATTC_DISCONNECT_EVT:` が来たら `wait` を解消する `give` を投げりゃええんじゃないの？わからんけど！

というわけで、まず  `ESP_GATTC_DISCONNECT_EVT:` 側を弄る。give しろ give 。

```BLEClient.cpp
        case ESP_GATTC_DISCONNECT_EVT: {
                // If we receive a disconnect event, set the class flag that indicates that we are
                // no longer connected.
                if ( !m_isConnected) m_semaphoreOpenEvt.give(evtParam->open.status); 
```

でもって受け側は以下のように `m_isConnected == false` なら繋がってねーじゃんチキショーという判定を入れる

```BLEClient.cpp
    uint32_t rc = m_semaphoreOpenEvt.wait("connect");   // Wait for the connection to complete.
    if ( !m_isConnected ) {
        ESP_LOGE(LOG_TAG, "m_semaphoreOpenEvt.wait terminated by disconnection" );
        ESP_LOGD(LOG_TAG, "<< connect(), rc=%d", rc==ESP_GATT_OK);
        return false;
    }
```

これで無限待機はしない。
我が家の場合、1度目が 100% 失敗するが、再度 BLEScan からやりなおすと、2回目の試行ではちゃんと接続できる。なんなんだ。
ペリフェラルが2つあるのだが、2つとも1回目失敗して2回目成功する。なんなんだ。

引き続き、一発目から成功するコードの書き方を探るか、Arduino-ESP32 を諦めて SDK 的に記述するか考えたい。


#ちなみに
動いていた(今も動いてる)コードってのは
https://qiita.com/ajtajta_j/items/fd17980e71ddecb74da3
で書いたものなんだけど、（動いているとは言え）見返すといろいろ恥ずかしいコードなのであんまり見ないでくださいw

#続報
1回目（100%失敗）と2回目（100%成功）のログを見比べるて、ひょっとして BLEClient の準備が間に合ってなくて失敗してるのか？と疑ってみて、advertise callback で device found の時点で BLEClient を作ってしまうようにしたら上手くうごいたぞ。わからんけど！


#さらに続報 2019/2/1
Arduino-ESP32 1.0.1 でやる場合は
[https://github.com/nkolban/esp32-snippets/issues/767](https://github.com/nkolban/esp32-snippets/issues/767) にて
wakwak-koba さんが指摘されているとおり `BLEClient::connect( BLEAddress address, esp_ble_addr_type_t type )` の `type` を適切に設定する、
または
chegewara さんが挙げているとおり `BLEClient::connect( BLEAdvertisedDevice* device )` のほうで呼ぶ
ことで回避できる、気がします（私の最新のコードは( BLEAdvertisedDevice* device ) のほうで呼んでいるから動いてる説）

自分で検証はまだできてませんが、取り急ぎ。（整理出来たら元の記事に集約してこちらは消すかも）

#最終の続報 2019/2/3
検証しましたが、たしかに
 `BLEClient::connect( BLEAddress address, esp_ble_addr_type_t type )` の `type` を適切に設定する、
(AE-TYBLE16 や micro:bit の場合は BLE_ADDR_TYPE_RANDOM)
または
 `BLEClient::connect( BLEAdvertisedDevice* device )` のほうで呼ぶ
で解決します。

自分のコードが動いてたのは前述の「advertise callback で device found の時点で BLEClient を作ってしまうようにしたら」の時に「advertise callback は BLEAdvertisedDevice* が解ってるから、こっちの関数で呼ぶかー」ってやってたからで、タイミングの問題じゃなくて呼ぶ関数の問題でした。うーん、気付かない私アホですみません。

まぁこれで解決したってことで！(1.0.2が来たらまた調べる必要あるやつかなーこれ）