/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void BLEGAPScanResponseEvent(object sender, Bluegiga.BLE.Events.GAP.ScanResponseEventArgs e) { Application.Current.Dispatcher.Invoke(delegate { MessageWriter.LogWrite("ble_evt_gap_scan_response: ", string.Format("rssi={0}, packet_type={1}, sender={2}, address_type={3}, bond={4}, data={5}", e.rssi, e.packet_type, BitConverter.ToString(e.sender), e.address_type, e.bond, BitConverter.ToString(e.data))); BLEPeripheral peripheral = FindDiscoveredPeripheral(e.sender); // If the responder is undiscovereed, add it to the collection if (peripheral == null) { peripheral = new BLEPeripheral(e.sender); discoveredPeripherals.Add(peripheral); } // Update RSSI peripheral.RSSI = e.rssi; peripheral.Bond = e.bond; // Parse packet byte[] remainingData = e.data; while (remainingData.Length > 0) { ushort elementLength = remainingData[0]; byte adType = remainingData[1]; byte[] element = remainingData.Skip(2).Take(elementLength - 1).ToArray(); if (!peripheral.AdData.ContainsKey(adType)) { peripheral.AdData.Add(adType, BitConverter.ToString(element)); } // Flags if (adType == Bluetooth.GenericAccessProfile.AD_Type.Get("Flags")) { peripheral.Flags = element.FirstOrDefault(); } // Complete local name if (adType == Bluetooth.GenericAccessProfile.AD_Type.Get("Shortened Local Name")) { peripheral.ShortenedLocalName = Encoding.ASCII.GetString(element); } // Complete local name if (adType == Bluetooth.GenericAccessProfile.AD_Type.Get("Complete Local Name")) { peripheral.Name = Encoding.ASCII.GetString(element); } remainingData = remainingData.Skip(elementLength + 1).ToArray(); } }); }
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); string[] BLE_Info = new string[5]; BLE_Info[0] = e.rssi.ToString(); BLE_Info[1] = e.packet_type.ToString(); BLE_Info[2] = ByteArrayToHexString(e.sender); BLE_Info[3] = e.address_type.ToString(); BLE_Info[4] = e.bond.ToString(); ThreadSafeDelegate(delegate { txtLog.AppendText(log); BLE_Base.Add_Device_to_DataTable(BLE_Info); }); }
private void GAPScanResponseHandler(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}]", e.rssi, e.packet_type, ByteArrayToHexString(e.sender), e.address_type, e.bond, ByteArrayToHexString(e.data) ); WriteTxtLog(log); }
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); }); }
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) ); List <Byte[]> services = AdvertisedServices(e.data); File.AppendAllText(logLocation, "Services Start" + Environment.NewLine); foreach (var service in services) { //Console.WriteLine(ByteArrayToHexString(service)); File.AppendAllText(logLocation, ByteArrayToHexString(service) + Environment.NewLine); } File.AppendAllText(logLocation, "Services End " + Environment.NewLine); //Console.WriteLine("Services End"); if (isMT(services)) { String mpbid; mpbid = ParseMPBID(e.data); if (!localTools.ContainsKey(ByteArrayToHexString(e.sender))) { Tool t = new Tool(); t.BluetoothAddress = e.sender; t.MPBID = mpbid; t.AddressType = e.address_type; t.RSSI = e.rssi; t.ID = localTools.Count() + 1; localTools.Add(ByteArrayToHexString(e.sender), t); Console.WriteLine("Found: " + mpbid + " : " + localTools.Count.ToString()); if (mpbid == "0007000D36" || mpbid == "0007005DF1") { Console.WriteLine("Found 5698-----------------------------------"); //Connect //ConnectToTool(t); } } } //Console.Write(log); Debug.Print(log); }
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. }
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 // 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); }); if (debug) { SetLogText(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); }); String logText = String.Format("=> TX ({0}) [ {1}]", cmd.Length, ByteArrayToHexString(cmd)) + Environment.NewLine; if (debug) { SetLogText(logText); } bglib.SendCommand(serialAPI, cmd); //while (bglib.IsBusy()) ; // update state app_state = STATE_CONNECTING; } }
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; } }
// 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); }); string macadr = ByteArrayToHexString(e.sender).Trim(); string macinfo = string.Format("Sensortag {0} RSSI: {1}", macadr.Replace(' ', ':'), e.rssi); if (!dicmac.ContainsKey(macadr)) { dicmac.Add(macadr, macinfo); } else { dicmac.Remove(macadr); dicmac.Add(macadr, macinfo); } ThreadSafeDelegate(delegate { int selix = cbxlistDevices.SelectedIndex; cbxlistDevices.Items.Clear(); cbxlistDevices.Items.AddRange(dicmac.Values.ToArray()); cbxlistDevices.SelectedIndex = selix; if (selix >= 0) { cbxlistDevices.SetItemChecked(selix, true); } }); // 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(cmd); //while (bglib.IsBusy()) ; // update state app_state = STATE_CONNECTING; } }
//Adevertising search event. // for master/scanner devices, the "gap_scan_response" event is a common entry-like point // this filters ad packets and display it into listview. // // //Search Event // 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 // This is a scan response event. This event is normally received by a Master which is scanning for advertisement and // scan response packets from Slaves. // Data Fiels: // [4]=int8, rssi; RSSI value(dBm), range=[-103 ~ -38]; // [5]=uint8,packet_type; Scan response header; // 0: Connectable Advertisement packet. // 2: Non Connectable Advertisement packet. // 4: Scan response packet. // 6: Discoverable advertisement packet. // [6~11]:bd_addr; Advertisers Bluetooth address. // [12]:uint8,address_type; Advertiser address type, // 1: random address; 0: public address // [13]:uint8,bond; Bond handle if there is known bond for this device, 0xff otherwise. // [14]:uint8 array, data; Scan response data. public void EventDevScanResponse(object sender, Bluegiga.BLE.Events.GAP.ScanResponseEventArgs e) { string mName = "(NoName)"; // 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 false 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()); } else if (this_field[0] == 0x09) {//Full name mName = System.Text.Encoding.ASCII.GetString(this_field.Skip(1).ToArray()); } #else if (this_field[0] == 0x09) {//Full name mName = System.Text.Encoding.ASCII.GetString(this_field.Skip(1).ToArray()); } #endif } } } //添加扫描信息到列表中; int rssi = Math.Abs(e.rssi); string macaddr = DatConvert.ByteArrayToHexString(e.sender); ThreadSafeDelegate(delegate { // //check whether this dev is already displayed in the list. //if it is not, we add it to the listbox,otherwise, just update. // ListViewItem lvS = listScanDev.FindItemWithText(macaddr);//查找列表中是否有重复设备; if (lvS != null) { lvS.SubItems[0].Text = mName; lvS.SubItems[1].Text = rssi.ToString(); lvS.SubItems[2].Text = DatConvert.ByteArrayToHexString(e.sender); } else { ListViewItem lv = new ListViewItem(mName); //[0]; lv.SubItems.Add(rssi.ToString()); //[1] lv.SubItems.Add(DatConvert.ByteArrayToHexString(e.sender)); //[2] lv.SubItems[2].Tag = e.bond; if (e.address_type == 1) { lv.SubItems.Add("Random"); //[3] } else { lv.SubItems.Add("Public"); //[3] } lv.SubItems.Add(e.bond.ToString()); //[4] lv.SubItems.Add(e.packet_type.ToString()); //[4]; listScanDev.Items.Add(lv); } }); }