public static UsbPacket CreateUSBPacketFromByteArray(byte[] byteArray) { uint offset = 0; UsbPacket usbPacket = new UsbPacket(); usbPacket.packetType = (UsbPacketType)byteArray[offset]; offset = offset + 1; usbPacket.reserved1 = byteArray[offset]; offset = offset + 1; usbPacket.reserved2 = BitConverter.ToInt16(byteArray, (int)offset); offset = offset + 2; usbPacket.packetId = BitConverter.ToInt16(byteArray, (int)offset); offset = offset + 2; usbPacket.reserved3 = BitConverter.ToInt16(byteArray, (int)offset); offset = offset + 2; usbPacket.dataSize = BitConverter.ToInt32(byteArray, (int)offset); offset = offset + 4; usbPacket.data = new byte[usbPacket.dataSize]; try { Array.Copy(byteArray, offset, usbPacket.data, 0, usbPacket.dataSize); } catch (ArgumentException) { File.AppendAllText(Path.Combine(Assembly.GetExecutingAssembly().Location, "bad-packets.txt"), BitConverter.ToString(byteArray)); Console.Error.WriteLine("Skipped bad packet"); usbPacket.packetId = -1; } return(usbPacket); }
public static void CreateUSBPacketByteArray(UsbPacket usbPacket, ref byte[] destinationArray) { CreateUSBPacketByteArray(usbPacket.packetType, usbPacket.packetId, usbPacket.dataSize, usbPacket.data, ref destinationArray); }
public void GarminWrite(UsbPacket usbPacket) { //TODO: Place this check ouside this method to make sure that multiple write calls are made if //data size is greater than MAX_BUFFER_SIZE /* * the size of all the data sent to the device is the size of the * usb data structure(3.2.2) plus the size of all the data sent (index 12+ of the structure) */ int theBytesToWrite = Marshal.SizeOf(usbPacket) + usbPacket.dataSize; int theBytesReturned = 0; // prepare and format the data to be sent byte[] dataAsArray = null; Utilities.CreateUSBPacketByteArray(usbPacket, ref dataAsArray); GCHandle gcDataHandle = GCHandle.Alloc(dataAsArray, GCHandleType.Pinned); IntPtr gcDataHandleAddress = gcDataHandle.AddrOfPinnedObject(); // prepare a destination address for the data to be written GCHandle gcReturnDataHandle = GCHandle.Alloc(theBytesReturned, GCHandleType.Pinned); IntPtr gcReturnDataHandleAddress = gcReturnDataHandle.AddrOfPinnedObject(); try { bool success = UnsafeNativeMethods.WriteFile( Handle, gcDataHandleAddress, theBytesToWrite, gcReturnDataHandleAddress, new Overlapped()); // format the data written at the addresses in a .net readable structure int returnedBytes = (int)Marshal.PtrToStructure(gcReturnDataHandleAddress, typeof(Int32)); if (success == false || returnedBytes != theBytesToWrite) { throw new InvalidOperationException("UnableToWriteToDevice"); } // If the packet size was an exact multiple of the USB packet // size, we must make a final write call with no data (3.2.3.1) if (theBytesToWrite % PacketSize == 0) { success = UnsafeNativeMethods.WriteFile( Handle, IntPtr.Zero, 0, gcReturnDataHandleAddress, new Overlapped()); } if (success == false) { throw new InvalidOperationException("Unable to write to device"); } } finally { gcDataHandleAddress = IntPtr.Zero; gcReturnDataHandleAddress = IntPtr.Zero; gcDataHandle.Free(); gcReturnDataHandle.Free(); } }