/// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void BLEConnectionDisconnectedEvent(object sender, Bluegiga.BLE.Events.Connection.DisconnectedEventArgs e)
        {
            Application.Current.Dispatcher.Invoke(delegate
            {
                MessageWriter.LogWrite("ble_evt_connection_disconnected: ", string.Format("connection={0}, reason={1}",
                                                                                          e.connection,
                                                                                          e.reason));

                BLEPeripheral peripheral;
                if (connectedDevices.TryRemoveByConnection(e.connection, out peripheral))
                {
                    peripheral.ConnectionState = BLEPeripheral.ConnState.Disconnected;
                }

                // Stop advertising
                cmd = bglib.BLECommandGAPEndProcedure();
                MessageWriter.LogWrite("ble_cmd_gap_end_procedure", "");
                bglib.SendCommand(SelectedPort, cmd);

                // Reset GAP Mode
                cmd = bglib.BLECommandGAPSetMode(0, 0);
                MessageWriter.LogWrite("ble_cmd_gap_set_mode: ", "discover=0, connect=0");
                bglib.SendCommand(SelectedPort, cmd);

                BLEScan();
            });
        }
Beispiel #2
0
        public override bool Connect(string deviceName)
        {
            if (!port.IsOpen)
            {
                if (!ConnectToBluegiga())
                {
                    return(false);
                }
            }

            bool           commandStarted   = false;
            bool           connectionEst    = false;
            byte           connectionHandle = 0;
            AutoResetEvent resp             = new AutoResetEvent(false);

            ConnectDirectEventHandler connectResp = delegate(object sender, ConnectDirectEventArgs e)
            {
                if (e.result == 0)
                {
                    commandStarted   = true;
                    connectionHandle = e.connection_handle;
                    resp.Set();
                }
            };

            StatusEventHandler connectionStatus = delegate(object sender, StatusEventArgs e)
            {
                connectionEst = true;
                resp.Set();
            };

            bluetooth.BLEResponseGAPConnectDirect += connectResp;
            bluetooth.BLEEventConnectionStatus    += connectionStatus;

            foreach (BluetoothDevice device in discoveredDevices)
            {
                if (device.Name.Equals(deviceName))
                {
                    this.device = device;
                    bluetooth.SendCommand(this.port, bluetooth.BLECommandGAPConnectDirect(device.BluetoothAddress, 0, 20, 40, 100, 1));
                    resp.WaitOne(200);
                    if (commandStarted)
                    {
                        this.device.ConnectionHandle = connectionHandle;
                        resp.WaitOne(1000);
                    }
                    break;
                }
            }

            bluetooth.BLEResponseGAPConnectDirect -= connectResp;
            bluetooth.BLEEventConnectionStatus    -= connectionStatus;

            if (connectionEst)
            {
                isConnected = true;
            }

            return(connectionEst);
        }
Beispiel #3
0
        public UInt16 att_handle_measurement_ccc = 0;             // heart rate measurement client characteristic configuration handle (to enable notifications)

        //-------------------------------------------------------------------------------------------------------------
        // NOTE: The ATTClientProcedureCompletedEvent is automatically triggered at the end of each event handler.
        //       The ATTClientProcedureCompletedEvent examines the "STATE" along with other data and decides
        //       what command to issue next.  In general each command triggers a corresponding event that
        //       performs some work and then triggers the ATTClientProcedureCompletedEvent.
        //-------------------------------------------------------------------------------------------------------------

        //-------------------------------------------------------------------------------------------------------------
        // For master/scanner devices, the "gap_scan_response" event is a common "entry-like" point
        // that filters ad packets to find devices which advertise the Heart Rate service.
        // Other services can be found as well. See https://www.bluetooth.com/specifications/gatt/services
        // for a list of Service Assigned Numbers (hexadecimal values are used).
        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 = findAllAdvertisedServices(e.data);

            // Check for 0x180D (the official Heart Rate service UUID),
            // using an "extension" method.
            if (ad_services.Any(a => a.SequenceEqual(new Byte[] { 0x18, 0x0D })))
            {
                // A device with the Heart Rate service has been found, so
                // connect to that device, triggering the ConnectionStatus event.

                // See Ref. p. 101, for info. about the Connect Direct command.
                // Parameters are:
                // Byte[] address, Byte addr_type, UInt16 conn_interval_min, UInt16 conn_interval_max, UInt16 timeout, UInt16 latency
                Byte[] cmd = bglib.BLECommandGAPConnectDirect(e.sender, e.address_type, 0x20, 0x30, 0x100, 0);

                // DEBUG: display bytes written
                ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("=> TX ({0}) [ {1}]", cmd.Length, ByteArrayToHexString(cmd)) + Environment.NewLine); });

                // Send the command, which then triggers the ConnectionStatus event.
                bglib.SendCommand(serialAPI, cmd);

                // Update the state to "connecting"
                app_state = STATE_CONNECTING;
            }

            // No callback function was specified. A callback function may be used.
            // Only the ConnectionStatus event handler is used in this application.
        }
Beispiel #4
0
        public void Connect_to_BLE_Device(string Addr, Bluegiga.BGLib bglib, SerialPort serialAPI, char symbol)
        {
            string[] AddrSplited = Addr.Split(symbol);
            byte[]   addr        = new byte[6];
            int      add         = 0;
            int      value       = 0;
            string   hex         = null;

            for (int i = 0; i < AddrSplited.Length - 1; i++)
            {
                value = Convert.ToInt32(AddrSplited[i], 16);
                byte charValue = (byte)value;
                addr[add++] = charValue;
            }


            //BLECommandGAPConnectDirect
            bglib.SendCommand(serialAPI, bglib.BLECommandGAPConnectDirect(addr, 0x00, 10, 250, 300, 0));
        }
Beispiel #5
0
        public void GAPScanResponseEvent(object sender, Bluegiga.BLE.Events.GAP.ScanResponseEventArgs e)
        {
#if PRINT_DEBUG
            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); });
#endif
            // 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());
                        }
                    }
                }
            }

            if (ad_services.Any(a => a.SequenceEqual((new Byte[] { 0x19, 0xb1, 0x00, 0x10, 0xE8, 0xF2,
                                                                   0x53, 0x7E, 0x4F, 0x6C, 0xD1, 0x04, 0x76, 0x8A, 0x01, 0x16 }) /*.Reverse()*/)))
            {
                // connect to this device
                Byte[] cmd = bglib.BLECommandGAPConnectDirect(e.sender, e.address_type, 0x06, 0x0C, 0x100, 0); // ~120/60 Hz min/max interval
#if PRINT_DEBUG
                ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("=> TX ({0}) [ {1}]", cmd.Length, ByteArrayToHexString(cmd)) + Environment.NewLine); });
#endif
                bglib.SendCommand(serialAPI, cmd);

                // update state
                app_state = STATE_CONNECTING;
            }
        }
Beispiel #6
0
        public UInt16 att_handle_measurement_ccc = 0;             // heart rate measurement client characteristic configuration handle (to enable notifications)

        // 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 Heart Rate 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 0x180D (official heart rate service UUID)
            if (ad_services.Any(a => a.SequenceEqual(new Byte[] { 0x18, 0x0D })))
            {
                // 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;
            }
        }
Beispiel #7
0
 public void Scan()
 {
     bglib.SendCommand(serialAPI, bglib.BLECommandGAPDiscover(1));
 }
Beispiel #8
0
 protected void SendCmd(Byte[] cmd)
 {
     bglib.SendCommand(serialAPI, cmd);
 }
 private void btnStartScan_Click(object sender, EventArgs e)
 {
     // send gap_discover(mode: 1)
     //serialAPI.Write(new Byte[] { 0, 1, 6, 2, 1 }, 0, 5);
     bglib.SendCommand(serialAPI, bglib.BLECommandGAPDiscover(1));
 }
Beispiel #10
0
        private void ScanThread()
        {
            DateTime mTimStart = DateTime.Now;

            while (true)
            {
                switch (c_BleDev.State)
                {
                case GhpBle.ACTTION_IDLE:
                    Thread.Sleep(50);
                    break;

#if false
                case GhpBle.ACTIION_ATTR_PAIR_CHECK:
                {
                    mTimStart = DateTime.Now;
                    while (c_BleDev.Busy)
                    {
                        TimeSpan mTimDif = DateTime.Now.Subtract(mTimStart);
                        if (mTimDif.Seconds > 3)
                        {
                            break;
                        }
                    }
                    c_BleDev.Busy = true;
                    byte[] cmd = bglib.BLECommandATTClientReadByType(c_BleDev.ConnHandle, 0x0001, 0xFFFF, new byte[] { 0x03, 0x28 });
                    bglib.SendCommand(comDev, cmd);

                    mTimStart = DateTime.Now;
                    while (c_BleDev.Busy)
                    {
                        TimeSpan mTimDif = DateTime.Now.Subtract(mTimStart);
                        if (mTimDif.Seconds > 3)
                        {
                            break;
                        }
                    }
                    if (c_BleDev.NeedPair)
                    {
                        if (c_BleDev.Paired == false)
                        {
                            c_BleDev.Busy = true;
                            byte[] cmd2 = bglib.BLECommandSMEncryptStart(c_BleDev.ConnHandle, 1);
                            bglib.SendCommand(comDev, cmd2);

                            mTimStart = DateTime.Now;
                            while (c_BleDev.Paired == false)
                            {
                                TimeSpan mTimDif = DateTime.Now.Subtract(mTimStart);
                                if (mTimDif.Seconds > 3)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            c_BleDev.State = GhpBle.ACTIONN_ATTR_PAIR_DONE;
                        }
                    }
                    else
                    {
                        c_BleDev.State = GhpBle.ACTIONN_ATTR_PAIR_DONE;
                    }
                }
                break;

                case GhpBle.ACTIONN_ATTR_PAIR_DONE:
                    if (c_BleDev.NeedPair && c_BleDev.Paired)
                    {
                        c_BleDev.State = GhpBle.ACTTION_SCAN_PRIMSRV;
                    }
                    break;
#endif
                case GhpBle.ACTTION_SCAN_PRIMSRV:
                {
                    c_BleDev.Busy = true;
                    Byte[] cmd = bglib.BLECommandATTClientReadByGroupType(c_BleDev.ConnHandle, 0x0001, 0xFFFF, new Byte[] { 0x00, 0x28 });
                    bglib.SendCommand(comDev, cmd);

                    mTimStart = DateTime.Now;
                    while (c_BleDev.Busy)
                    {
                        TimeSpan mTimDif = DateTime.Now.Subtract(mTimStart);
                        if (mTimDif.Seconds > 10)
                        {
                            break;
                        }
                    }
                    c_BleDev.State = GhpBle.ACTTION_SCAN_PRIMSRV_DONE;
                }
                break;

                case GhpBle.ACTTION_SCAN_PRIMSRV_DONE:
                    break;

                case GhpBle.ACTTION_SCAN_ATTRIB:
                    if (c_BleDev.CurrentPrimSrv != null)
                    {
                        if (c_BleDev.CurrentPrimSrv.AttScanDone == false)
                        {
                            //
                            //scan all attribute first.
                            //
                            c_BleDev.Busy = true;
                            Byte[] cmd = bglib.BLECommandATTClientFindInformation(c_BleDev.ConnHandle, c_BleDev.CurrentPrimSrv.Start, c_BleDev.CurrentPrimSrv.End);
                            bglib.SendCommand(comDev, cmd);

                            mTimStart = DateTime.Now;
                            while (c_BleDev.Busy)
                            {
                                TimeSpan mTimDif = DateTime.Now.Subtract(mTimStart);
                                if (mTimDif.Seconds > 20)
                                {
                                    break;
                                }
                            }

                            //
                            //Now read user description of each attribute;
                            //
                            foreach (CAttribute attr in c_BleDev.CurrentPrimSrv.AttrList)
                            {
                                c_BleDev.Busy        = true;
                                c_BleDev.AttReadDone = false;
                                cmd = bglib.BLECommandATTClientReadByHandle(c_BleDev.ConnHandle, attr.UserDescHandle);
                                bglib.SendCommand(comDev, cmd);
                                while (c_BleDev.Busy && c_BleDev.AttReadDone == false)
                                {
                                }
                                if (c_BleDev.AttReadDone == true)
                                {
                                    attr.AttName = Encoding.UTF8.GetString(c_BleDev.AttReadValue);
                                }
                            }
                            c_BleDev.CurrentPrimSrv.AttScanDone = true;
                        }
                    }
                    c_BleDev.State = GhpBle.ACTTION_SCAN_ATTRIB_DONE;
                    break;

                case GhpBle.ACTTION_SCAN_ATTRIB_DONE:
                    break;

                case GhpBle.ACTTION_ATTR_READ:
                    while (c_BleDev.Busy == false && c_BleDev.AttReadDone == false)
                    {
                        ;
                    }
                    c_BleDev.State = GhpBle.ACTIONN_ATTR_READ_DONE;
                    break;

                case GhpBle.ACTIONN_ATTR_READ_DONE:
                    break;

                case GhpBle.ACTTION_ATTR_WRITE:
                    break;

                default:
                    break;
                }
            }
        }