private static Packet WriteSimplePacket(HidStream stream, ushort opcode) { using (Packet packet = new Packet()) { packet.WriteByte(0);// report id packet.WriteUInt16(opcode); packet.WriteBytes(new byte[62]); byte[] buffer = packet.GetWrittenBuffer(); Crc16.InsertCrc(buffer, 1, 7);// offset for the report id byte stream.Write(buffer); byte[] resultBufferWithReportId = new byte[65]; stream.Read(resultBufferWithReportId); if (resultBufferWithReportId[0] != 0) { return(null); } byte[] resultBuffer = new byte[64]; Buffer.BlockCopy(resultBufferWithReportId, 1, resultBuffer, 0, resultBuffer.Length); // All handshake packets should have a result code of 1 if (resultBuffer[2] != 1 || resultBuffer[0] != (byte)opcode || resultBuffer[1] != opcode >> 8) { return(null); } if (!Crc16.ValidateCrc(resultBuffer)) { return(null); } Packet result = new Packet(true, resultBuffer); result.Index = 8; return(result); } }
public Packet WritePacket(OpCodes op1, byte op2, Packet packet, byte op3 = 0) { lock (locker) { int numPackets = 1; int offset = 0; byte[] completeBuffer = null; if (packet != null) { completeBuffer = packet.GetWrittenBuffer(); numPackets = (completeBuffer.Length / 0x38) + 1; } bool allowsLongOffset = false; int offsetOffset = 2; int lengthOffset = 4; switch (op1) { case OpCodes.DriverLayerSetKeyValues: case OpCodes.DriverLayerUpdateRealtimeLighting: case OpCodes.LayerSetLightValues: offsetOffset = 2; lengthOffset = 5; allowsLongOffset = true; break; case OpCodes.LayerSetKeyPressLightingEffect: case OpCodes.LayerSetKeyValues: case OpCodes.LayerFnSetKeyValues: case OpCodes.LayerSetMacros: offsetOffset = 2; lengthOffset = 4; break; } const int reportHeaderLen = 1; try { for (int i = 0; i < numPackets; i++) { byte[] report = new byte[65]; report[1] = (byte)op1; report[2] = op2; if (op3 > 0) { // Not really an op, used for setting keyboard data buffers report[3] = op3; } if (completeBuffer != null) { int numBytesToWrite = Math.Min(0x38, completeBuffer.Length - offset); Buffer.BlockCopy(completeBuffer, offset, report, reportHeaderLen + 8, numBytesToWrite); if (numPackets > 1) { report[reportHeaderLen + offsetOffset + 0] = (byte)offset; report[reportHeaderLen + offsetOffset + 1] = (byte)(offset >> 8); if (allowsLongOffset) { report[reportHeaderLen + offsetOffset + 3] = (byte)(offset >> 16); } report[reportHeaderLen + lengthOffset] = (byte)numBytesToWrite; } } Crc16.InsertCrc(report, reportHeaderLen, 6 + reportHeaderLen); stream.Write(report); byte[] resultBuffer = GetResponse((byte)op1, op2); if (resultBuffer[0] != (byte)op1 /* || resultBuffer[1] != op2*/) { return(null); } if (!Crc16.ValidateCrc(resultBuffer)) { return(null); } if (i == numPackets - 1) { Packet result = new Packet(true, resultBuffer); result.Index = 8; lastSentMessage = Environment.TickCount; return(result); } offset += 0x38; } } catch { return(null); } return(null); } }