//クライアントのプロビジョニングを処理とサーバーとの接続/インターフェースを行う。
bool connectToServer() {
NimBLEClient* pClient = nullptr;
//再利用できるクライアントの検索
if(NimBLEDevice::getClientListSize()) {
pClient = NimBLEDevice::getClientByPeerAddress(advDevice->getAddress());
if(pClient){
//このデバイスをすでに知っている場合は、connect()の第2引数にfalseセットすることで
//サービスデータベースを更新しないようにする。これにより、かなりの時間と電力を節約できる
if(!pClient->connect(advDevice, false)) {
Serial.println("Reconnect failed");
return false;
}
Serial.println("Reconnected client");
}else {
//このデバイスを知っているクライアントがまだない場合、使用できる切断中のクライアントを調べる
pClient = NimBLEDevice::getDisconnectedClient();
}
}
//再利用するクライアントがない場合、新しいクライアントを作成する
if(!pClient) {
if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) {
Serial.println("Max clients reached - no more connections available");
return false;
}
pClient = NimBLEDevice::createClient();
Serial.println("New client created");
pClient->setClientCallbacks(&clientCB, false);
//初期接続パラメータの設定: これらの設定は、15ms間隔、0ms待ち時間、120msタイムアウト
//これらの設定は、3クライアントが確実に接続できる安全な設定です。タイムアウトはインターバルの倍数で、最小は100ms
//最小間隔:12 * 1.25ms = 15ms、最大間隔:12 * 1.25ms = 15ms、待ち時間 0ms、タイムアウト51 * 10ms = 510ms
pClient->setConnectionParams(12,12,0,51);
//接続が完了するまでの待機時間(秒)を設定。デフォルトは30。
pClient->setConnectTimeout(5);
if (!pClient->connect(advDevice)) {
//クライアントを作成したが、接続に失敗
NimBLEDevice::deleteClient(pClient);
Serial.println("Failed to connect, deleted client");
return false;
}
}
if(!pClient->isConnected()) {
if (!pClient->connect(advDevice)) {
Serial.println("Failed to connect");
return false;
}
}
//接続完了
Serial.print("Connected to: ");
Serial.println(pClient->getPeerAddress().toString().c_str());
Serial.print("RSSI: ");
Serial.println(pClient->getRssi());
NimBLERemoteService *pSvc = nullptr;
//複数扱うためにvectorを使う
std::vector<NimBLERemoteCharacteristic*> *pChrs = nullptr;
NimBLERemoteDescriptor *pDsc = nullptr;
//HIDサービスを取得する
pSvc = pClient->getService(serviceUUID);
if (pSvc) {
//Serial.println("pSvc : HIDサービス取得成功");
// 複数のCharacterisiticsを取得(リフレッシュtrue)
pChrs = pSvc->getCharacteristics(true);
}else{
//Serial.println("pSvc : HIDサービス取得失敗");
}
if (pChrs) {
//Serial.println("pChrs : Characterisitics取得成功");
// 複数のReport Characterisiticsの中からNotify属性を持っているものをCallbackに登録する
for (int i = 0; i < pChrs->size(); i++) {
// Read Write処理部は省略
//registerForNotify()は非推奨となり、subscribe()/unsubscribe()に置き換えられた
// Subscribeパラメータのデフォルトは、notifications=true、notifyCallback=nullptr、response=false
//接続機器からのcharacteristic変更を通知する属性はNotifyとIndicateのみでコールバックを登録する
//Notify属性
if (pChrs->at(i)->canNotify()) {
//Serial.printf("SetNotify UUID: %s\n",pChrs->at(i)->getUUID().toString().c_str());
//if (!pChrs->at(i)->registerForNotify(notifyCB)) {
if(!pChrs->at(i)->subscribe(true, notifyCB,true)) {
//コールバック登録(サブスクライブ)失敗した場合は切断する
pClient->disconnect();
return false;
}
} else
//Indicate属性(Noitfyとの違いは接続元[ESP32]からの応答を要求する)
if (pChrs->at(i)->canIndicate()) {
if(!pChrs->at(i)->subscribe(false, notifyCB,true)) {
pClient->disconnect();
return false;
}
}
}
}else{
//Serial.println("pChrs : Characterisitics取得失敗");
}
Serial.println("Done with this device!");
return true;
}