private void SendPacket(GarminUSBPacket aPacket) { var bytesToWrite = 12 + (int)aPacket.Size; int theBytesReturned; IntPtr pPacket = Marshal.AllocHGlobal(bytesToWrite); Marshal.StructureToPtr(aPacket, pPacket, false); bool r = APIs.WriteFile(handle, pPacket, bytesToWrite, out theBytesReturned, IntPtr.Zero); Marshal.FreeHGlobal(pPacket); if (!r) { throw new GarminUsbException(Strings.ErrorCommunicatingWithDevice); } // If the packet size was an exact multiple of the USB packet size, we must make a final write call with no data if (bytesToWrite % usbPacketSize == 0) { r = APIs.WriteFile(handle, IntPtr.Zero, 0, out theBytesReturned, IntPtr.Zero); if (!r) { throw new GarminUsbException(Strings.ErrorCommunicatingWithDevice); } } }
private void StopUSBCommunication() { try { if (handle != IntPtr.Zero) { APIs.CloseHandle(handle); handle = IntPtr.Zero; } } finally { ReadingNow = false; } }
private static APIs.DeviceInterfaceDetailData GetDeviceInfo(IntPtr hDevInfoSet, Guid deviceGUID, out string deviceID, int devicePortIndex) { // Get a Device Interface Data structure. // -------------------------------------- APIs.DeviceInterfaceData interfaceData = new APIs.DeviceInterfaceData(); APIs.CRErrorCodes crResult; IntPtr startingDevice; APIs.DevinfoData infoData = new APIs.DevinfoData(); APIs.DeviceInterfaceDetailData detailData = new APIs.DeviceInterfaceDetailData(); bool result = true; IntPtr ptrInstanceBuf; uint requiredSize = 0; interfaceData.Init(); infoData.Size = Marshal.SizeOf(typeof(APIs.DevinfoData)); detailData.Size = Marshal.SizeOf(typeof(APIs.DeviceInterfaceDetailData)); result = APIs.SetupDiEnumDeviceInterfaces( hDevInfoSet, 0, ref deviceGUID, (uint)devicePortIndex, ref interfaceData); if (!result) { if (Marshal.GetLastWin32Error() == APIs.ERROR_NO_MORE_ITEMS) { deviceID = string.Empty; return(new APIs.DeviceInterfaceDetailData()); } else { throw new ApplicationException("[CCore::GetDeviceInfo] Error when retriving device info"); } } //Get a DevInfoDetailData and DeviceInfoData // ------------------------------------------ // First call to get the required size. result = APIs.SetupDiGetDeviceInterfaceDetail( hDevInfoSet, ref interfaceData, IntPtr.Zero, 0, ref requiredSize, ref infoData); // Create the buffer. detailData.Size = 5; // Call with the correct buffer result = APIs.SetupDiGetDeviceInterfaceDetail( hDevInfoSet, ref interfaceData, ref detailData, // ref devDetailBuffer, requiredSize, ref requiredSize, ref infoData); if (!result) { System.Windows.Forms.MessageBox.Show(Marshal.GetLastWin32Error().ToString()); throw new ApplicationException("[CCore::GetDeviceInfo] Can not get SetupDiGetDeviceInterfaceDetail"); } startingDevice = infoData.DevInst; //Get current device data ptrInstanceBuf = Marshal.AllocHGlobal(1024); crResult = (APIs.CRErrorCodes)APIs.CM_Get_Device_ID(startingDevice, ptrInstanceBuf, 1024, 0); if (crResult != APIs.CRErrorCodes.CR_SUCCESS) { throw new ApplicationException("[CCore::GetDeviceInfo] Error calling CM_Get_Device_ID: " + crResult); } // We have the pnp string of the parent device. deviceID = Marshal.PtrToStringAuto(ptrInstanceBuf); Marshal.FreeHGlobal(ptrInstanceBuf); return(detailData); }
private GarminUSBPacket GetPacket() { GarminUSBPacket packet; var bufferSize = 0; var buffer = new byte[0]; while (true) { // Read async data until the driver returns less than the // max async data size, which signifies the end of a packet var tempBuffer = new byte[APIs.ASYNC_DATA_SIZE]; int bytesReturned; IntPtr pInBuffer = Marshal.AllocHGlobal(0); IntPtr pOutBuffer = Marshal.AllocHGlobal(APIs.ASYNC_DATA_SIZE); bool r = APIs.DeviceIoControl( handle.ToInt32(), CTL_CODE(0x00000022, 0x850, 0, 0), pInBuffer, 0, pOutBuffer, APIs.ASYNC_DATA_SIZE, out bytesReturned, 0); Marshal.Copy(pOutBuffer, tempBuffer, 0, APIs.ASYNC_DATA_SIZE); Marshal.FreeHGlobal(pInBuffer); Marshal.FreeHGlobal(pOutBuffer); if (!r) { throw new GarminUsbException(Strings.ErrorCommunicatingWithDevice); } bufferSize += APIs.ASYNC_DATA_SIZE; var newBuffer = new byte[bufferSize]; if (buffer.Length > 0) { Array.Copy(buffer, 0, newBuffer, 0, buffer.Length); } Array.Copy(tempBuffer, 0, newBuffer, bufferSize - APIs.ASYNC_DATA_SIZE, tempBuffer.Length); buffer = newBuffer; if (bytesReturned != APIs.ASYNC_DATA_SIZE) { packet = new GarminUSBPacket(buffer); break; } } // If this was a small "signal" packet, read a real // packet using ReadFile if (packet.Type == 0 && packet.Id == 2) { var newBuffer = new byte[MAX_BUFFER_SIZE]; var bytesReturned = 0; // A full implementation would keep reading (and queueing) // packets until the driver returns a 0 size buffer. bool r = APIs.ReadFile(handle, newBuffer, MAX_BUFFER_SIZE, ref bytesReturned, IntPtr.Zero); if (!r) { throw new GarminUsbException(Strings.ErrorCommunicatingWithDevice); } return(new GarminUSBPacket(newBuffer)); } return(packet); }
private void StartUSBCommunication() { ReadingNow = true; var guid = new Guid("2C9C45C2-8E7D-4C08-A12D-816BBAE722C0"); string deviceId; const int portIndex = 0; IntPtr hDevInfoSet = APIs.SetupDiGetClassDevs(ref guid, 0, IntPtr.Zero, (int)(APIs.DeviceFlags.DigCDDeviceInterface | APIs.DeviceFlags.DigCFPresent)); APIs.DeviceInterfaceDetailData mDetailedData = GetDeviceInfo(hDevInfoSet, guid, out deviceId, portIndex); handle = APIs.CreateFile(mDetailedData.DevicePath, FileAccess.Read | FileAccess.Write, FileShare.None, IntPtr.Zero, FileMode.Open, 0x00000080, IntPtr.Zero); // Did we get a handle? if ((int)handle < 0) { throw new GarminUsbException(Strings.ErrorFindingDevice); } IntPtr usbPacketSizePointer = Marshal.AllocHGlobal(sizeof(Int16)); int bytesReturned; bool r = APIs.DeviceIoControl( handle.ToInt32(), CTL_CODE(0x00000022, 0x851, 0, 0), IntPtr.Zero, 0, usbPacketSizePointer, (uint)sizeof(int), out bytesReturned, 0); if (!r) { throw new GarminUsbException(Strings.ErrorCommunicatingWithDevice); } usbPacketSize = (Int16)Marshal.PtrToStructure(usbPacketSizePointer, typeof(Int16)); Marshal.FreeHGlobal(usbPacketSizePointer); // Tell the device that we are starting a session. var startSessionPacket = new GarminUSBPacket { Id = 5 }; SendPacket(startSessionPacket); GarminUSBPacket packet; while (true) { packet = GetPacket(); if (packet.Type == 0 && packet.Id == 6) { break; } } }