/***** 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));

                    }
                }

            }
        }
Exemple #2
0
        public void ATTClientAttributeValueEvent(object sender, Bluegiga.BLE.Events.ATTClient.AttributeValueEventArgs e)
        {
            String log = String.Format("ble_evt_attclient_attribute_value: connection={0}, atthandle={1}, type={2}, value=[ {3}]" + Environment.NewLine,
                e.connection,
                e.atthandle,
                e.type,
                ByteArrayToHexString(e.value)
                );
            Console.Write(log);
            ThreadSafeDelegate(delegate { txtLog.AppendText(log); });

            // check for a new value from the connected peripheral's temperature measurement attribute
            if (e.connection == connection_handle && e.atthandle == att_handle_measurement)
            {
                Byte htm_flags = e.value[0];
                int htm_exponent = e.value[4];
                int htm_mantissa = (e.value[3] << 16) | (e.value[2] << 8) | e.value[1];
                if (htm_exponent > 127)
                {
                    // # convert to signed 8-bit int
                    htm_exponent = htm_exponent - 256;
                }
                float htm_measurement = htm_mantissa * (float)Math.Pow(10, htm_exponent);
                char temp_type = 'C';
                if ((htm_flags & 0x01) == 0x01)
                {
                    // value sent is Fahrenheit, not Celsius
                    temp_type = 'F';
                }

                // display actual measurement
                ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("Temperature: {0}\u00B0 {1}", htm_measurement, temp_type) + Environment.NewLine); });
            }
        }
Exemple #3
0
        public void ATTClientAttributeValueEvent(object sender, Bluegiga.BLE.Events.ATTClient.AttributeValueEventArgs e)
        {
            String log = String.Format("ble_evt_attclient_attribute_value: connection={0}, atthandle={1}, type={2}, value=[ {3}]" + Environment.NewLine,
                e.connection,
                e.atthandle,
                e.type,
                ByteArrayToHexString(e.value)
                );
            Console.Write(log);
            ThreadSafeDelegate(delegate { txtLog.AppendText(log); });

            // check for a new value from the connected peripheral's
            if (e.connection == adrTIUser)
            {
                switch ((TI_Sensor_Data)e.atthandle)
                {
                    case TI_Sensor_Data.Temperature:
                        double tempA = st.getTempAmbient(e.value);
                        double tempIR = st.extractTargetTemperature(e.value, tempA);
                        ThreadSafeDelegate(delegate { labTempAmbient.Text = tempA.ToString("f2") + " °C"; });
                        ThreadSafeDelegate(delegate { labTempIR.Text = tempIR.ToString("f2") + " °C"; });
                        break;
                    case TI_Sensor_Data.Humidity:
                        ThreadSafeDelegate(delegate { labHumidity.Text = st.convertHumidity(e.value).ToString("f2") + " rel. %"; });
                        break;
                    case TI_Sensor_Data.Barometer:
                        ThreadSafeDelegate(delegate { labBarometer.Text = st.convertBarometer(e.value).ToString("f2") + " mbar"; });
                        break;
                    case TI_Sensor_Data.Movement:
                        p3d_a = st.convertAccelerometer(e.value);
                        p3d_g = st.convertGyroscope(e.value);
                        p3d_m = st.convertMagnetometer(e.value);

                        ThreadSafeDelegate(delegate
                        {
                            dataGridView1.Rows[0].Cells[1].Value = p3d_a.x.ToString("f3");
                            dataGridView1.Rows[0].Cells[2].Value = p3d_a.y.ToString("f3");
                            dataGridView1.Rows[0].Cells[3].Value = p3d_a.z.ToString("f3");
                            dataGridView1.Rows[1].Cells[1].Value = p3d_g.x.ToString("f3");
                            dataGridView1.Rows[1].Cells[2].Value = p3d_g.y.ToString("f3");
                            dataGridView1.Rows[1].Cells[3].Value = p3d_g.z.ToString("f3");
                            dataGridView1.Rows[2].Cells[1].Value = p3d_m.x.ToString("f3");
                            dataGridView1.Rows[2].Cells[2].Value = p3d_m.y.ToString("f3");
                            dataGridView1.Rows[2].Cells[3].Value = p3d_m.z.ToString("f3");
                        });
                        break;
                    case TI_Sensor_Data.Luxometer:
                        ThreadSafeDelegate(delegate { labLuxometer.Text = st.convertLuxometer(e.value).ToString("f2") + " lux"; });
                        break;
                    default:
                        break;
                }
            }
        }
Exemple #4
0
 public void GAPScanResponseEvent(object sender, Bluegiga.BLE.Events.GAP.ScanResponseEventArgs e)
 {
     String log = String.Format("ble_evt_gap_scan_response:" + Environment.NewLine + "\trssi={0}, packet_type={1}, bd_addr=[ {2}], address_type={3}, bond={4}, data=[ {5}]" + Environment.NewLine,
         (SByte)e.rssi,
         (SByte)e.packet_type,
         ByteArrayToHexString(e.sender),
         (SByte)e.address_type,
         (SByte)e.bond,
         ByteArrayToHexString(e.data)
         );
     Console.Write(log);
     ThreadSafeDelegate(delegate { txtLog.AppendText(log); });
 }
Exemple #5
0
 public void SystemBootEvent(object sender, Bluegiga.BLE.Events.System.BootEventArgs e)
 {
     String log = String.Format("ble_evt_system_boot:" + Environment.NewLine + "\tmajor={0}, minor={1}, patch={2}, build={3}, ll_version={4}, protocol_version={5}, hw={6}" + Environment.NewLine,
         e.major,
         e.minor,
         e.patch,
         e.build,
         e.ll_version,
         e.protocol_version,
         e.hw
         );
     Console.Write(log);
     ThreadSafeDelegate(delegate { txtLog.AppendText(log); });
 }
Exemple #6
0
        public void ATTClientAttributeValueEvent(object sender, Bluegiga.BLE.Events.ATTClient.AttributeValueEventArgs e)
        {
            String log = String.Format("ble_evt_attclient_attribute_value: connection={0}, atthandle={1}, type={2}, value=[ {3}]" + Environment.NewLine,
                e.connection,
                e.atthandle,
                e.type,
                ByteArrayToHexString(e.value)
                );
            Console.Write(log);
            ThreadSafeDelegate(delegate { txtLog.AppendText(log); });

            // check for a new value from the connected peripheral's heart rate measurement attribute
            if (e.connection == connection_handle && e.atthandle == att_handle_measurement)
            {
                Byte hr_flags = e.value[0];
                int hr_measurement = e.value[1];

                // display actual measurement
                ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("Heart rate: {0} bpm", hr_measurement) + Environment.NewLine); });
            }
        }
Exemple #7
0
        public void ATTClientFindInformationFoundEvent(object sender, Bluegiga.BLE.Events.ATTClient.FindInformationFoundEventArgs e)
        {
            String log = String.Format("ble_evt_attclient_find_information_found: connection={0}, chrhandle={1}, uuid=[ {2}]" + Environment.NewLine,
                e.connection,
                e.chrhandle,
                ByteArrayToHexString(e.uuid)
                );
            Console.Write(log);
            ThreadSafeDelegate(delegate { txtLog.AppendText(log); });

            // check for thermometer measurement characteristic
            if (e.uuid.SequenceEqual(new Byte[] { 0x1C, 0x2A }))
            {
                ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("Found attribute w/UUID=0x2A1C: handle={0}", e.chrhandle) + Environment.NewLine); });
                att_handle_measurement = e.chrhandle;
            }
            // check for subsequent client characteristic configuration
            else if (e.uuid.SequenceEqual(new Byte[]  { 0x02, 0x29 }) && att_handle_measurement > 0)
            {
                ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("Found attribute w/UUID=0x2902: handle={0}", e.chrhandle) + Environment.NewLine); });
                att_handle_measurement_ccc = e.chrhandle;
            }
        }
 /// <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));
 }
        /// <summary>
        /// AtrributeWrite-データ送信完了メソッド(イベント呼び出し)
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">Args</param>
        void bgLib_BLEEventATTClientProcedureCompleted(object sender, Bluegiga.BLE.Events.ATTClient.ProcedureCompletedEventArgs e)
        {
            //serialCommProcessMessage(this, "ProcedureCompleted Result : " + e.result);

            // e.result == 0 ⇒データ送信正常完了
            if (e.result == 0)
                isAttributeWrited = true;
        }
Exemple #10
0
        // for master/scanner devices, the "gap_scan_response" event is a common entry-like point
        // this filters ad packets to find devices which advertise the Health Thermometer service
        public void GAPScanResponseEvent(object sender, Bluegiga.BLE.Events.GAP.ScanResponseEventArgs e)
        {
            String log = String.Format("ble_evt_gap_scan_response: rssi={0}, packet_type={1}, sender=[ {2}], address_type={3}, bond={4}, data=[ {5}]" + Environment.NewLine,
                (SByte)e.rssi,
                e.packet_type,
                ByteArrayToHexString(e.sender),
                e.address_type,
                e.bond,
                ByteArrayToHexString(e.data)
                );
            Console.Write(log);
            ThreadSafeDelegate(delegate { txtLog.AppendText(log); });

            // pull all advertised service info from ad packet
            List<Byte[]> ad_services = new List<Byte[]>();
            Byte[] this_field = {};
            int bytes_left = 0;
            int field_offset = 0;
            for (int i = 0; i < e.data.Length; i++)
            {
                if (bytes_left == 0)
                {
                    bytes_left = e.data[i];
                    this_field = new Byte[e.data[i]];
                    field_offset = i + 1;
                }
                else
                {
                    this_field[i - field_offset] = e.data[i];
                    bytes_left--;
                    if (bytes_left == 0)
                    {
                        if (this_field[0] == 0x02 || this_field[0] == 0x03)
                        {
                            // partial or complete list of 16-bit UUIDs
                            ad_services.Add(this_field.Skip(1).Take(2).Reverse().ToArray());
                        }
                        else if (this_field[0] == 0x04 || this_field[0] == 0x05)
                        {
                            // partial or complete list of 32-bit UUIDs
                            ad_services.Add(this_field.Skip(1).Take(4).Reverse().ToArray());
                        }
                        else if (this_field[0] == 0x06 || this_field[0] == 0x07)
                        {
                            // partial or complete list of 128-bit UUIDs
                            ad_services.Add(this_field.Skip(1).Take(16).Reverse().ToArray());
                        }
                    }
                }
            }

            // check for 0x1809 (official health thermometer service UUID)
            if (ad_services.Any(a => a.SequenceEqual(new Byte[] { 0x18, 0x09 }))) {
                // connect to this device
                Byte[] cmd = bglib.BLECommandGAPConnectDirect(e.sender, e.address_type, 0x20, 0x30, 0x100, 0); // 125ms interval, 125ms window, active scanning
                // DEBUG: display bytes written
                ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("=> TX ({0}) [ {1}]", cmd.Length, ByteArrayToHexString(cmd)) + Environment.NewLine); });
                bglib.SendCommand(serialAPI, cmd);
                //while (bglib.IsBusy()) ;

                // update state
                app_state = STATE_CONNECTING;
            }
        }
Exemple #11
0
        // the "connection_status" event occurs when a new connection is established
        public void ConnectionStatusEvent(object sender, Bluegiga.BLE.Events.Connection.StatusEventArgs e)
        {
            String log = String.Format("ble_evt_connection_status: connection={0}, flags={1}, address=[ {2}], address_type={3}, conn_interval={4}, timeout={5}, latency={6}, bonding={7}" + Environment.NewLine,
                e.connection,
                e.flags,
                ByteArrayToHexString(e.address),
                e.address_type,
                e.conn_interval,
                e.timeout,
                e.latency,
                e.bonding
                );
            Console.Write(log);
            ThreadSafeDelegate(delegate { txtLog.AppendText(log); });

            if ((e.flags & 0x05) == 0x05)
            {
                // connected, now perform service discovery
                connection_handle = e.connection;
                ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("Connected to {0}", ByteArrayToHexString(e.address)) + Environment.NewLine); });
                Byte[] cmd = bglib.BLECommandATTClientReadByGroupType(e.connection, 0x0001, 0xFFFF, new Byte[] { 0x00, 0x28 }); // "service" UUID is 0x2800 (little-endian for UUID uint8array)
                // DEBUG: display bytes written
                ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("=> TX ({0}) [ {1}]", cmd.Length, ByteArrayToHexString(cmd)) + Environment.NewLine); });
                bglib.SendCommand(serialAPI, cmd);
                //while (bglib.IsBusy()) ;

                // update state
                app_state = STATE_FINDING_SERVICES;
            }
        }
Exemple #12
0
        public void ATTClientProcedureCompletedEvent(object sender, Bluegiga.BLE.Events.ATTClient.ProcedureCompletedEventArgs e)
        {
            String log = String.Format("ble_evt_attclient_procedure_completed: connection={0}, result={1}, chrhandle={2}" + Environment.NewLine,
                e.connection,
                e.result,
                e.chrhandle
                );
            Console.Write(log);
            ThreadSafeDelegate(delegate { txtLog.AppendText(log); });

            // check if we just finished searching for services
            if (app_state == STATE_FINDING_SERVICES)
            {
                if (att_handlesearch_end > 0)
                {
                    //print "Found 'Health Thermometer' service with UUID 0x1809"

                    // found the Health Thermometer service, so now search for the attributes inside
                    Byte[] cmd = bglib.BLECommandATTClientFindInformation(e.connection, att_handlesearch_start, att_handlesearch_end);
                    // DEBUG: display bytes written
                    ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("=> TX ({0}) [ {1}]", cmd.Length, ByteArrayToHexString(cmd)) + Environment.NewLine); });
                    bglib.SendCommand(serialAPI, cmd);
                    //while (bglib.IsBusy()) ;

                    // update state
                    app_state = STATE_FINDING_ATTRIBUTES;
                }
                else
                {
                    ThreadSafeDelegate(delegate { txtLog.AppendText("Could not find 'Health Thermometer' service with UUID 0x1809" + Environment.NewLine); });
                }
            }
            // check if we just finished searching for attributes within the thermometer service
            else if (app_state == STATE_FINDING_ATTRIBUTES)
            {
                if (att_handle_measurement_ccc > 0)
                {
                    //print "Found 'Health Thermometer' measurement attribute with UUID 0x2A1C"

                    // found the measurement + client characteristic configuration, so enable indications
                    // (this is done by writing 0x02 to the client characteristic configuration attribute)
                    Byte[] cmd = bglib.BLECommandATTClientAttributeWrite(e.connection, att_handle_measurement_ccc, new Byte[] { 0x02 });
                    // DEBUG: display bytes written
                    ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("=> TX ({0}) [ {1}]", cmd.Length, ByteArrayToHexString(cmd)) + Environment.NewLine); });
                    bglib.SendCommand(serialAPI, cmd);
                    //while (bglib.IsBusy()) ;

                    // update state
                    app_state = STATE_LISTENING_MEASUREMENTS;
                }
                else
                {
                    ThreadSafeDelegate(delegate { txtLog.AppendText("Could not find 'Health Thermometer' measurement attribute with UUID 0x2A1C" + Environment.NewLine); });
                }
            }
        }
Exemple #13
0
        public void ATTClientGroupFoundEvent(object sender, Bluegiga.BLE.Events.ATTClient.GroupFoundEventArgs e)
        {
            String log = String.Format("ble_evt_attclient_group_found: connection={0}, start={1}, end={2}, uuid=[ {3}]" + Environment.NewLine,
                e.connection,
                e.start,
                e.end,
                ByteArrayToHexString(e.uuid)
                );
            Console.Write(log);
            ThreadSafeDelegate(delegate { txtLog.AppendText(log); });

            // found "service" attribute groups (UUID=0x2800), check for thermometer service
            if (e.uuid.SequenceEqual(new Byte[] { 0x09, 0x18 }))
            {
                ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("Found attribute group for service w/UUID=0x1809: start={0}, end=%d", e.start, e.end) + Environment.NewLine); });
                att_handlesearch_start = e.start;
                att_handlesearch_end = e.end;
            }
        }
Exemple #14
0
        /// <summary>
        /// Event handler for when the connection status changes.
        /// </summary>
        private void BGLib_BLEEventConnectionStatus(object sender, Bluegiga.BLE.Events.Connection.StatusEventArgs e)
        {
            ConnectionStatusFlags flags = (ConnectionStatusFlags)e.flags;

            // Run in Dispatcher.Invoke Lambda as the event is in a different thread to the UI...
            this.Dispatcher.Invoke(() =>
                {
                    if (flags.HasFlag(ConnectionStatusFlags.Connected))
                    {
                        //SendOutput("Device connected!");
                        connection = e.connection;
                        IsConnected = true;
                        IsAdvertising = false;
                    }
                    else if (flags.HasFlag(ConnectionStatusFlags.Encrypted))
                    {
                        //SendOutput("Connection encrypted!");
                        IsEncrypted = true;
                    }
                });
        }
Exemple #15
0
 /// <summary>
 /// Called when the remote device disconnects.
 /// </summary>        
 private void BGLib_BLEEventConnectionDisconnected(object sender, Bluegiga.BLE.Events.Connection.DisconnectedEventArgs e)
 {
     // Run in Dispatcher.Invoke Lambda as the event is in a different thread to the UI...
     this.Dispatcher.Invoke(() =>
         {
             DisconnectedReason reason = (DisconnectedReason)e.reason;
             SendOutput("Device disconnected. Reason: " + reason.ToString());
             StopTimer();
             IsEncrypted = false;
             IsConnected = false;
             StartAdvertisingMode();
         });
 }