public void AcceptConnectionRequest(ulong bdAddr, byte role) { var data = new byte[7]; data[0] = (byte)(bdAddr & 0xFF); data[1] = (byte)((bdAddr & 0xFF00) >> 8); data[2] = (byte)((bdAddr & 0xFF0000) >> 16); data[3] = (byte)((bdAddr & 0xFF000000) >> 24); data[4] = (byte)((bdAddr & 0xFF00000000) >> 32); data[5] = (byte)((bdAddr & 0xFF0000000000) >> 40); data[6] = role; var opcode = new Opcode(OpcodeGroupField.LinkControl, OpcodeCommandField.AcceptConnectionRequest); _SendHCICommand(opcode, data, true); }
private void _SendHCICommand(Opcode command, byte[] parameterData, bool returnImmediately) { var cmdData = new byte[3 + (parameterData != null ? parameterData.Length : 0)]; var packet = new UsbSetupPacket(0x20, 0x00, 0x0000, 0x0000, (short)cmdData.Length); cmdData[0] = (byte)(command.Data & 0xFF); cmdData[1] = (byte)((command.Data >> 8) & 0xFF); if (parameterData != null && parameterData.Length > 0) { cmdData[2] = (byte)parameterData.Length; for (int i = 0; i < parameterData.Length; i++) cmdData[3 + i] = parameterData[i]; } int transferred; _device.ControlTransfer(ref packet, cmdData, cmdData.Length, out transferred); if (transferred != cmdData.Length) throw new InvalidOperationException(String.Format("Failed to send command; sent {0} bytes instead of {1}", transferred, cmdData.Length)); if (!returnImmediately) { //Wait for command to complete _WaitForCompletion(command); } }
private void _WaitForCompletion(Opcode command) { while (true) { lock (_completedCommands) { if (_completedCommands.Contains(command)) { _completedCommands.Remove(command); break; } } Thread.Sleep(10); } }
private void _SendHCICommand(Opcode command, bool returnImmediately) { _SendHCICommand(command, null, returnImmediately); }
private void _SendHCICommand(Opcode command, byte[] parameterData) { _SendHCICommand(command, parameterData, false); }
private void hci_DataReceived(object sender, EndpointDataEventArgs e) { switch ((HCIEvent)e.Buffer[0]) { case HCIEvent.InquiryComplete: { lock (_completedCommands) { _completedCommands.Add(new Opcode(OpcodeGroupField.LinkControl, OpcodeCommandField.Inquiry)); } break; } case HCIEvent.InquiryResult: { var opcode = new Opcode(OpcodeGroupField.LinkControl, OpcodeCommandField.Inquiry); if (!_commandData.ContainsKey(opcode)) _commandData.Add(opcode, new List<InquiryResult>()); var list = _commandData[opcode] as List<InquiryResult>; int responses = Convert.ToInt32(e.Buffer[2]); int offset = 3; for (int i = 0; i < responses; i++) { list.Add(new InquiryResult(Utilities.GetLEULong(e.Buffer, offset + 0, 6), e.Buffer[offset + 6], e.Buffer[offset + 7], e.Buffer[offset + 8], (uint)Utilities.GetLEULong(e.Buffer, offset + 9, 3), (ushort)Utilities.GetLEULong(e.Buffer, offset + 12, 2))); offset += 14; } break; } case HCIEvent.ConnectionComplete: { Logger.WriteLine("Connection Complete, Status: " + e.Buffer[2].ToString("X2")); ushort connectionHandle = (ushort)(e.Buffer[3] | (e.Buffer[4] << 8)); ulong bdAddr = Utilities.GetLEULong(e.Buffer, 5, 6); //Raise event out if (ConnectionComplete != null) ConnectionComplete(this, new HCIEventEventArgs(e.Buffer, e.Count)); break; } case HCIEvent.DisconnectionComplete: { Logger.WriteLine("Disconnection Complete, Status: " + e.Buffer[2].ToString("X2")); break; } case HCIEvent.ConnectionRequest: { var bdAddr = Utilities.GetLEULong(e.Buffer, 2, 6); var deviceClass = Utilities.GetLEULong(e.Buffer, 8, 3); byte linkType = e.Buffer[11]; Logger.WriteLine(String.Format("Connection Request Received, BD_ADDR {0}, class {1}, link type {2}", bdAddr.ToString("X12"), deviceClass.ToString("X6"), linkType.ToString("X2"))); //Accept this request (or do whatever with it) if (ConnectionRequestReceived != null) ConnectionRequestReceived(this, new HCIEventEventArgs(e.Buffer, e.Count)); break; } case HCIEvent.RemoteNameRequestComplete: { var opcode = new Opcode(OpcodeGroupField.LinkControl, OpcodeCommandField.RemoteNameRequest); if (!_commandData.ContainsKey(opcode)) _commandData.Add(opcode, ASCIIEncoding.ASCII.GetString(e.Buffer, 9, 248).Trim(new char[] {'\0'} )); lock (_completedCommands) { _completedCommands.Add(opcode); } break; } case HCIEvent.QoSSetupComplete: { Logger.WriteLine("QoS Setup Complete"); break; } case HCIEvent.Complete: { var command = new Opcode(e.Buffer, 3); lock (_completedCommands) { _completedCommands.Add(command); } break; } case HCIEvent.Status: { var command = new Opcode(e.Buffer, 4); break; } case HCIEvent.PINCodeRequestEvent: { var bdAddr = Utilities.GetLEULong(e.Buffer, 2, 6); //Send the reply SendPINCodeReply(bdAddr, String.Empty); break; } default: { //Uh? Logger.WriteLine("Unknown HCI event: " + e.Buffer[0].ToString("X2")); break; } } }
private void _SendHCICommand(Opcode command) { _SendHCICommand(command, false); }
public void SetDiscoverableMode(bool discoverable) { var opcode = new Opcode(OpcodeGroupField.HCBaseband, OpcodeCommandField.WriteScanEnable); _SendHCICommand(opcode, new byte[] {discoverable ? (byte)0x03 : (byte)0x01}); }
public void SetLocalName(string name) { var data = new byte[name.Length + 1]; Array.Copy(ASCIIEncoding.ASCII.GetBytes(name), data, name.Length); var opcode = new Opcode(OpcodeGroupField.HCBaseband, OpcodeCommandField.WriteLocalName); _SendHCICommand(opcode, data); }
public void SetDeviceClass(uint deviceClass) { var data = new byte[3]; data[0] = (byte)(deviceClass & 0xFF); data[1] = (byte)((deviceClass >> 8) & 0xFF); data[2] = (byte)((deviceClass >> 16) & 0xFF); var opcode = new Opcode(OpcodeGroupField.HCBaseband, OpcodeCommandField.WriteDeviceClass); _SendHCICommand(opcode, data); }
//NOTE: This doesn't work if you send a PIN, not sure why. public void SendPINCodeReply(ulong bdAddr, string pin) { Opcode opcode; var data = new byte[6 + (String.IsNullOrEmpty(pin) ? 0 : pin.Length + 1)]; data[0] = (byte)(bdAddr & 0xFF); data[1] = (byte)((bdAddr & 0xFF00) >> 8); data[2] = (byte)((bdAddr & 0xFF0000) >> 16); data[3] = (byte)((bdAddr & 0xFF000000) >> 24); data[4] = (byte)((bdAddr & 0xFF00000000) >> 32); data[5] = (byte)((bdAddr & 0xFF0000000000) >> 40); if (!String.IsNullOrEmpty(pin)) { data[6] = (byte)pin.Length; for (int i = 0; i < pin.Length; i++) data[7 + i] = (byte)pin[i]; opcode = new Opcode(OpcodeGroupField.LinkControl, OpcodeCommandField.SendPINCodeRequestReply); } else opcode = new Opcode(OpcodeGroupField.LinkControl, OpcodeCommandField.SendPINCodeRequestNegativeReply); _SendHCICommand(opcode, data, true); }
public string GetRemoteName(InquiryResult device) { var data = new byte[10]; var ret = String.Empty; data[0] = (byte)(device.BDAddr & 0xFF); data[1] = (byte)((device.BDAddr & 0xFF00) >> 8); data[2] = (byte)((device.BDAddr & 0xFF0000) >> 16); data[3] = (byte)((device.BDAddr & 0xFF000000) >> 24); data[4] = (byte)((device.BDAddr & 0xFF00000000) >> 32); data[5] = (byte)((device.BDAddr & 0xFF0000000000) >> 40); data[6] = device.PageScanRepetitionMode; data[8] = (byte)(device.ClockOffset & 0xFF); data[9] = (byte)((byte)((device.ClockOffset & 0xFF00) >> 8) | (byte)0x80); var opcode = new Opcode(OpcodeGroupField.LinkControl, OpcodeCommandField.RemoteNameRequest); _SendHCICommand(opcode, data); if (_commandData.ContainsKey(opcode)) { ret = _commandData[opcode] as string; _commandData.Remove(opcode); } return ret; }
public List<InquiryResult> DoInquiryScan(int timeoutSeconds) { const int iac = (int)AssignedNumbers.GeneralUnlimitedIAC; var data = new byte[5]; int timeout = Convert.ToInt32(Math.Round(timeoutSeconds / 1.28)); if (timeout <= 0 || timeout > 0x30) throw new ArgumentException("Invalid timeout"); var ret = new List<InquiryResult>(); data[0] = (byte)(iac & 0xFF); data[1] = (byte)((iac & 0xFF00) >> 8); data[2] = (byte)((iac & 0xFF0000) >> 16); data[3] = Convert.ToByte(timeout); var opcode = new Opcode(OpcodeGroupField.LinkControl, OpcodeCommandField.Inquiry); _SendHCICommand(opcode, data); if (_commandData.ContainsKey(opcode)) { ret = _commandData[opcode] as List<InquiryResult>; _commandData.Remove(opcode); } return ret; }
public void Connect(ulong bdAddr, byte pageScanRepetitionMode, ushort clockOffset) { var data = new byte[13]; data[0] = (byte)(bdAddr & 0xFF); data[1] = (byte)((bdAddr & 0xFF00) >> 8); data[2] = (byte)((bdAddr & 0xFF0000) >> 16); data[3] = (byte)((bdAddr & 0xFF000000) >> 24); data[4] = (byte)((bdAddr & 0xFF00000000) >> 32); data[5] = (byte)((bdAddr & 0xFF0000000000) >> 40); data[6] = (byte)0x18; data[7] = (byte)0x00; data[8] = pageScanRepetitionMode; data[9] = 0x00; data[10] = (byte)(clockOffset & 0xFF); data[11] = (byte)(((clockOffset >> 8) & 0xFF) | 0x80); data[12] = 0x00; var opcode = new Opcode(OpcodeGroupField.LinkControl, OpcodeCommandField.CreateConnection); _SendHCICommand(opcode, data, true); }