/***** GAPScanResponse検知メソッド(bgLibイベント呼び出し) *****/ private void bgLib_BLEEventGAPScanResponse(object sender, Bluegiga.BLE.Events.GAP.ScanResponseEventArgs e) { // データパケットの長さが25以上であれば、UUIDが乗っていないかチェックする if (e.data.Length > 25) { byte[] data_buf = new byte[16]; for (int i = 0; i < data_buf.Length; i++) data_buf[i] = e.data[i + 9]; // データパケットにUUIDが乗っていた場合 if (Object.ReferenceEquals(data_buf, PLEN2_TX_CHARACTERISTIC_UUID) && bleConnectState == BLEState.NotConnected) { bleConnectState = BLEState.Connecting; // PLEN2からのアドバタイズなので、接続を試みる bgLib.SendCommand(serialPort, bgLib.BLECommandGAPConnectDirect(e.sender, 0, 60, 76, 100, 0)); } } else { // 本来の接続手順を実装する。(具体的には以下の通りです。) // 1. ble_cmd_gap_connect_direct() // 2. ble_cmd_attclient_find_information() // 3. ble_evt_attclient_find_information_found()を処理し、UUIDを比較 // a. UUIDが一致する場合は、そのキャラクタリスティックハンドルを取得 → 接続完了 // b. 全てのキャラクタリスティックについてUUIDが一致しない場合は、4.以降の処理へ // 4. MACアドレスを除外リストに追加した後、ble_cmd_connection_disconnect() // 5. 再度ble_cmd_gap_discove() // 6. 1.へ戻る。ただし、除外リストとMACアドレスを比較し、該当するものには接続をしない。 // CAUTION!: 以下は横着した実装。本来は上記の手順を踏むべき。 // PLEN2からのアドバタイズなので、接続を試みる Int64 key = 0; // キー作成 for (int index = 0; index < 6; index++) key += (Int64)e.sender[index] << (index * 8); // 取得したキーに対してまだ接続していない場合,接続を試みる // ※connectedDictは他スレッドからの参照もありうるので排他制御 if (bleConnectState == BLEState.NotConnected) { lock(connectedDict) { // 取得したキーに対して,すでに接続を試みたならばスルー if (connectedDict.ContainsKey(key) == true && connectedDict[key] != BLEState.NotConnected) { return; } // 取得したキーをリストに追加,状態を接続要求中へ if (connectedDict.ContainsKey(key) == true) connectedDict.Add(key, BLEState.Connecting); else connectedDict[key] = BLEState.Connecting; // 自分の接続状態を更新 bleConnectState = BLEState.Connecting; // 取得したキーに対して接続を試みる(接続完了後イベント発生) bgLib.SendCommand(serialPort, bgLib.BLECommandGAPConnectDirect(e.sender, 0, 60, 76, 100, 0)); } } } }
/// <summary> /// 半二重通信メソッド /// </summary> private void halfDuplexComm() { serialCommProcessMessage(this, "HalfDuplexCommunication Started"); sendedMfxCommandCnt = 0; // カウントリセット try { /*----- 半二重通信ここから -----*/ bgLib.SendCommand(serialPort, bgLib.BLECommandGAPEndProcedure()); while (bgLib.IsBusy() == true) Thread.Sleep(1); Thread.Sleep(10); bgLib.SendCommand(serialPort, bgLib.BLECommandConnectionDisconnect(0)); while (bgLib.IsBusy() == true) Thread.Sleep(1); // PLEN2との接続を試みる Thread.Sleep(10); serialCommProcessMessage(this, "PLEN2 searching..."); bleConnectState = BLEState.NotConnected; bgLib.SendCommand(serialPort, bgLib.BLECommandGAPDiscover(1)); while (bleConnectState != BLEState.Connected) Thread.Sleep(1); /*-- ここからPLEN2と接続中 --*/ serialCommProcessMessage(this, "PLEN2 Connected"); serialCommProcessBLEConncted(this); foreach (PLEN.MFX.BLEMfxCommand sendMfxCommand in sendMfxCommandList) { // 送信データを文字列からbyte配列に変換 byte[] mfxCommandArray = System.Text.Encoding.ASCII.GetBytes(sendMfxCommand.strConvertedMfx); serialCommProcessMessage(this, "【" + sendMfxCommand.Name + "】 is sending..."); /*---- ここからモーションデータ送信 -----*/ /*-- header --*/ isAttributeWrited = false; byte[] test = System.Text.Encoding.ASCII.GetBytes("#IN"); bgLib.SendCommand(serialPort, bgLib.BLECommandATTClientAttributeWrite(0, 31, System.Text.Encoding.ASCII.GetBytes("#IN"))); while (isAttributeWrited == false) Thread.Sleep(1); Thread.Sleep(DELAY_INTERVAL); isAttributeWrited = false; bgLib.SendCommand(serialPort, bgLib.BLECommandATTClientAttributeWrite(0, 31, mfxCommandArray.Take(20).ToArray())); while (isAttributeWrited == false) Thread.Sleep(1); Thread.Sleep(DELAY_INTERVAL); isAttributeWrited = false; bgLib.SendCommand(serialPort, bgLib.BLECommandATTClientAttributeWrite(0, 31, mfxCommandArray.Skip(20).Take(10).ToArray())); while (isAttributeWrited == false) Thread.Sleep(1); Thread.Sleep(DELAY_INTERVAL); serialCommProcessMessage(this, "headler written."); Thread.Sleep(50); /*-- frame --*/ for (int index = 0; index < (mfxCommandArray.Length - 30) / 100; index++) { isAttributeWrited = false; bgLib.SendCommand(serialPort, bgLib.BLECommandATTClientAttributeWrite(0, 31, mfxCommandArray.Skip(30 + index * 100).Take(20).ToArray())); while (isAttributeWrited == false) Thread.Sleep(1); Thread.Sleep(DELAY_INTERVAL); isAttributeWrited = false; bgLib.SendCommand(serialPort, bgLib.BLECommandATTClientAttributeWrite(0, 31, mfxCommandArray.Skip(50 + index * 100).Take(20).ToArray())); while (isAttributeWrited == false) Thread.Sleep(1); Thread.Sleep(DELAY_INTERVAL); isAttributeWrited = false; bgLib.SendCommand(serialPort, bgLib.BLECommandATTClientAttributeWrite(0, 31, mfxCommandArray.Skip(70 + index * 100).Take(20).ToArray())); while (isAttributeWrited == false) Thread.Sleep(1); Thread.Sleep(DELAY_INTERVAL); isAttributeWrited = false; bgLib.SendCommand(serialPort, bgLib.BLECommandATTClientAttributeWrite(0, 31, mfxCommandArray.Skip(90 + index * 100).Take(20).ToArray())); while (isAttributeWrited == false) Thread.Sleep(1); Thread.Sleep(DELAY_INTERVAL); isAttributeWrited = false; bgLib.SendCommand(serialPort, bgLib.BLECommandATTClientAttributeWrite(0, 31, mfxCommandArray.Skip(110 + index * 100).Take(20).ToArray())); while (isAttributeWrited == false) Thread.Sleep(1); Thread.Sleep(DELAY_INTERVAL); serialCommProcessMessage(this, "frame written. [" + ((index + 1) * 100).ToString() + "/" + (mfxCommandArray.Length - 30).ToString() + "]"); Thread.Sleep(50); } serialCommProcessMessage(this, "【" + sendMfxCommand.Name + "】send Complete. ..."); sendedMfxCommandCnt++; serialCommProcessMfxCommandSended(this); Thread.Sleep(500); } // 終了イベントを発生 serialCommProcessMessage(this, "Communication Finished"); serialCommProcessFinished(this, new SerialCommProcessFinishedEventArgs(serialPort.PortName, sendMfxCommandList)); connectedDict[connectedBLEKey] = BLEState.SendCompleted; } catch (Exception e) { serialCommProcessMessage(this, e.Message); } finally { /*----- 半二重通信ここまで -----*/ bgLib.SendCommand(serialPort, bgLib.BLECommandConnectionDisconnect(0)); while (bgLib.IsBusy() == true) Thread.Sleep(1); bleConnectState = BLEState.NotConnected; } }
/// <summary> /// BLEクライアント接続完了メソッド(イベント呼び出し) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void bgLib_BLEEventConnectionStatus(object sender, Bluegiga.BLE.Events.Connection.StatusEventArgs e) { // PLENと接続完了 if ((e.flags & 0x01) != 0) { // アドレスリストを更新(接続中→接続完了へ) // ※connectedDictは他スレッドからも操作されるので排他制御 lock (connectedDict) { // アドレス作成 Int64 key = 0; for (int index = 0; index < 6; index++) key += (Int64)e.address[index] << (index * 8); // 状態更新(接続完了) connectedDict[key] = BLEState.Connected; connectedBLEKey = key; } serialCommProcessMessage(this, "Connected"); bleConnectState = BLEState.Connected; } // 再度接続を試みる else bgLib.SendCommand(serialPort, bgLib.BLECommandGAPDiscover(1)); }