// 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) #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_FINDING_SERVICES; } }
private void BLEPerformNextTask(BLEPeripheral peripheral) { // Find all attributes if (peripheral.Attributes.Count() == 0) { ushort start = 0x0001; ushort end = 0xFFFF; cmd = bglib.BLECommandATTClientFindInformation(peripheral.Connection, start, end); MessageWriter.LogWrite("ble_cmd_att_client_find_information: ", string.Format("connection={0}, start={1}, end={2}", peripheral.Connection, start, end)); bglib.SendCommand(SelectedPort, cmd); } // Have attributes been found? else if (peripheral.Services.Count() == 0) { // Perform service discovery ushort start = 0x0001; ushort end = 0xFFFF; byte[] primaryService = new byte[] { 0x00, 0x28 }; cmd = bglib.BLECommandATTClientReadByGroupType(peripheral.Connection, start, end, primaryService); MessageWriter.LogWrite("ble_cmd_att_client_read_by_group_type: ", string.Format("connection={0}, start={1}, end={2}, uuid={3}", peripheral.Connection, start, end, BitConverter.ToString(primaryService))); bglib.SendCommand(SelectedPort, cmd); } else if (!peripheral.Services.ContainsKey("CustomService")) { MessageWriter.LogWrite("Invalid device selected"); peripheral.Disconnect(); } else if (peripheral.attHandleCCC.Count > 0) { // Enable indications byte[] indications = new byte[] { 0x03, 0x00 }; byte[] cmd = bglib.BLECommandATTClientAttributeWrite(peripheral.Connection, peripheral.attHandleCCC.Peek(), indications); MessageWriter.LogWrite("ble_cmd_att_client_attribute_write: ", string.Format("connection={0}, att_handle={1}, data={2}", peripheral.Connection, peripheral.attHandleCCC.Dequeue(), BitConverter.ToString(indications))); bglib.SendCommand(SelectedPort, cmd); } // Is the low power mode state known? else if (peripheral.Characteristics.ContainsKey("LPM")) { if (peripheral.Characteristics["LPM"].ValueAttribute.Handle > 0 && peripheral.LowPowerMode == BLEPeripheral.LPM.Unknown) //TODO Low-Power mode key not found { // Check sleep mode cmd = bglib.BLECommandATTClientReadByHandle(peripheral.Connection, peripheral.Characteristics["LPM"].ValueAttribute.Handle); MessageWriter.LogWrite("ble_cmd_att_client_read_by_handle: ", string.Format("connection={0}, handle={1}", peripheral.Connection, peripheral.Characteristics["LPM"].ValueAttribute.Handle)); bglib.SendCommand(SelectedPort, cmd); } } }
//------------------------------------------------------------------------------------------------------------- // Event handler for the ConnectionStatus event. // 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); }); // Check the flags to see if a connection was completed. // Ref: p. 41 for links, see p. 96 for flag values if ((e.flags & 0x05) == 0x05) { // Connected, now perform service discovery. // Save the connection_handle value. connection_handle = e.connection; ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("Connected to {0}", ByteArrayToHexString(e.address)) + Environment.NewLine); }); // Create the ATTClientReadByGroup command. // "service" UUID is 0x2800 (little-endian for UUID uint8array). // Ref: https://www.bluetooth.com/specifications/gatt/declarations // Get a "list" of all services provided. Byte[] cmd = bglib.BLECommandATTClientReadByGroupType( e.connection, 0x0001, 0xFFFF, new Byte[] { 0x00, 0x28 }); // DEBUG: display bytes written ThreadSafeDelegate(delegate { txtLog.AppendText(String.Format("=> TX ({0}) [ {1}]", cmd.Length, ByteArrayToHexString(cmd)) + Environment.NewLine); }); // Send the command, triggering the ATTClientGroupFoundEvent and // the ProcedureCompleted event. Ref. p. 53. bglib.SendCommand(serialAPI, cmd); // Update the application state. app_state = STATE_FINDING_SERVICES; } }
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; } } }