ScpControl/Bluetooth/BthDongle.L2cap.cs (126 lines of code) (raw):

using System; namespace ScpControl.Bluetooth { public partial class BthDongle { #region L2CAP Commands /// <summary> /// Writes a Logical Link Control and Adaption Layer Protocol command packet to a Bluetooth host device. /// </summary> /// <param name="handle">The Usb device handle.</param> /// <param name="data">The payload (command) to send.</param> /// <returns></returns> private int L2CAP_Command(byte[] handle, byte[] data) { var transfered = 0; var buffer = new byte[64]; buffer[0] = handle[0]; buffer[1] = (byte)(handle[1] | 0x20); buffer[2] = (byte)(data.Length + 4); buffer[3] = 0x00; buffer[4] = (byte)(data.Length); buffer[5] = 0x00; buffer[6] = 0x01; buffer[7] = 0x00; // add payload to buffer Buffer.BlockCopy(data, 0, buffer, 8, data.Length); // send data to device WriteBulkPipe(buffer, data.Length + 8, ref transfered); // return transfered byte count return transfered; } /// <summary> /// Connection request packets are sent to create a channel between two devices. /// </summary> /// <remarks>BLUETOOTH SPECIFICATION Version 1.0 A page 278</remarks> /// <param name="handle">The HCI handle.</param> /// <param name="id">The packet id.</param> /// <param name="dcid">The Destination Channel Identifier.</param> /// <param name="psm">The Protocol and Service Multiplexer to request.</param> /// <returns>The byte count sent to the Bluetooth host.</returns> private int L2CAP_Connection_Request(byte[] handle, byte id, byte[] dcid, L2CAP.PSM psm) { var buffer = new byte[8]; buffer[0] = 0x02; buffer[1] = id; buffer[2] = 0x04; buffer[3] = 0x00; buffer[4] = (byte)psm; buffer[5] = 0x00; buffer[6] = dcid[0]; buffer[7] = dcid[1]; return L2CAP_Command(handle, buffer); } /// <summary> /// When a unit receives a Connection Request packet, it must send a Connection Response packet. /// </summary> /// <remarks>BLUETOOTH SPECIFICATION Version 1.0 A page 279</remarks> /// <remarks>BLUETOOTH SPECIFICATION Version 1.0 A page 278</remarks> /// <param name="handle">The HCI handle.</param> /// <param name="id">The packet id.</param> /// <param name="dcid">The Destination Channel Identifier.</param> /// <param name="scid">The Source Channel Identifier.</param> /// <param name="result">The result of the connection request.</param> /// <param name="status">Only defined for Result = Pending. Indicates the status of the connection.</param> /// <returns>The byte count sent to the Bluetooth host.</returns> private int L2CAP_Connection_Response(byte[] handle, byte id, byte[] dcid, byte[] scid, L2CAP.ConnectionResponseResult result, L2CAP.ConnectionResponseStatus status = L2CAP.ConnectionResponseStatus.NoFurtherInformationAvailable) { var buffer = new byte[12]; buffer[0] = 0x03; buffer[1] = id; buffer[2] = 0x08; buffer[3] = 0x00; buffer[4] = scid[0]; buffer[5] = scid[1]; buffer[6] = dcid[0]; buffer[7] = dcid[1]; buffer[8] = (byte) result; buffer[9] = 0x00; if (result == L2CAP.ConnectionResponseResult.ConnectionPending) { buffer[10] = (byte) status; buffer[11] = 0x00; } else { buffer[10] = 0x00; buffer[11] = 0x00; } return L2CAP_Command(handle, buffer); } private int L2CAP_Configuration_Request(byte[] handle, byte id, byte[] dcid, bool mtu = true) { var buffer = new byte[mtu ? 12 : 8]; buffer[0] = 0x04; buffer[1] = id; buffer[2] = (byte)(mtu ? 0x08 : 0x04); buffer[3] = 0x00; buffer[4] = dcid[0]; buffer[5] = dcid[1]; buffer[6] = 0x00; buffer[7] = 0x00; if (mtu) { buffer[8] = 0x01; buffer[9] = 0x02; buffer[10] = 0x96; buffer[11] = 0x00; } return L2CAP_Command(handle, buffer); } private int L2CAP_Configuration_Response(byte[] handle, byte id, byte[] scid) { var buffer = new byte[10]; buffer[0] = 0x05; buffer[1] = id; buffer[2] = 0x06; buffer[3] = 0x00; buffer[4] = scid[0]; buffer[5] = scid[1]; buffer[6] = 0x00; buffer[7] = 0x00; buffer[8] = 0x00; buffer[9] = 0x00; return L2CAP_Command(handle, buffer); } private int L2CAP_Disconnection_Request(byte[] handle, byte id, byte[] dcid, byte[] scid) { var buffer = new byte[8]; buffer[0] = 0x06; buffer[1] = id; buffer[2] = 0x04; buffer[3] = 0x00; buffer[4] = dcid[0]; buffer[5] = dcid[1]; buffer[6] = scid[0]; buffer[7] = scid[1]; return L2CAP_Command(handle, buffer); } private int L2CAP_Disconnection_Response(byte[] handle, byte id, byte[] dcid, byte[] scid) { var buffer = new byte[8]; buffer[0] = 0x07; buffer[1] = id; buffer[2] = 0x04; buffer[3] = 0x00; buffer[4] = dcid[0]; buffer[5] = dcid[1]; buffer[6] = scid[0]; buffer[7] = scid[1]; return L2CAP_Command(handle, buffer); } #endregion } }