public UsbStream CreateUsbStream(int writeEndpoint, int readEndpoint) { UsbStream s = null; lock (s_openStreams) { if (s_openStreams[m_controllerIndex] == null) { s_openStreams[m_controllerIndex] = new ArrayList(); } ArrayList streams = (ArrayList)s_openStreams[m_controllerIndex]; // if this is the first UsbStream associated with this controller, then start the controller if (streams.Count == 0) { // UsbController.GetController(m_controllerIndex).Start(); Start(); } try { s = new UsbStream(m_controllerIndex, writeEndpoint, readEndpoint); } catch (Exception e) { Stop(); throw e; } streams.Add(s); } return(s); }
/// <summary> /// Starts and configures the USBstream. /// </summary> /// <returns>True if properly started and configured. False otherwise.</returns> public static bool Start() { stream = null; UsbController[] usbControllers = UsbController.GetControllers(); if (usbControllers.Length < 1) return false; //Program has failed to run UsbController controller = usbControllers[0]; try { ConfigureUsbController(controller); if (!controller.Start()) return false; stream = controller.CreateUsbStream(USBSTREAM_WRITE_ENDPOINT, UsbStream.NullEndpoint); } catch { return false; } UsbController.PortState controllerStatus = controller.Status; while (controllerStatus != UsbController.PortState.Running) { controllerStatus = controller.Status; Thread.Sleep(1000); //Wait to let usb configure and initiate. } return true; }
public bool Stop() { bool ret = false; // Dispose all open streams and clear the list associated with this controller try { ArrayList streams = s_openStreams[m_controllerIndex]; if (streams != null) { while (streams.Count != 0) { UsbStream stream = (UsbStream)streams[0]; try { stream.Close(); } catch // swallow any exception { } finally { // the stream should already be gone from the array, but just in case... streams.Remove(stream); } } } } finally { ret = nativeStop(); } return(ret); }
static void MouseAndPingerLoop(UsbStream mouse, UsbStream pinger) { // Allocate in and out packets for "TinyBooter" simulation WireProtocol.WP_Packet inPacket; // Allocate packet for Pinger input UInt16 seq = 0; // Initialize Pinger packet sequence number // While done button is not pressed while (buttons.done.Read()) { // Perform these operations once every 10 milliseconds (actually a bit more than 10 milliseconds) // We've asked the host to query for mouse info at least every 10 milliseconds, but it actually // queries every 8 milliseconds - it's OK not to respond to every query. Thread.Sleep(10); byte xChange = 0; byte yChange = 0; // Make the mouse move by 3 steps each sample time if any movement button is pressed if (!buttons.up.Read()) yChange = 0xFD; if (!buttons.down.Read()) yChange = 3; if (!buttons.left.Read()) xChange = 0xFD; if (!buttons.right.Read()) xChange = 3; // Report to host the condition of "movement" or of the buttons SendMouseReport(mouse, !buttons.b1.Read(), !buttons.b2.Read(), !buttons.b3.Read(), xChange, yChange); // If a good WireProtocol packet was received from the host if (WireProtocol.ReadPacket(pinger, out inPacket)) { RespondToPacket(pinger, inPacket, seq); } } // Wait for the done button to be released while (!buttons.done.Read()) ; }
// Sends the given WP_Packet (header) and public static void SendPacket(UsbStream stream, WP_Packet packet, byte[] data) { int index; // Create a buffer whose size is large enough to contain both the WP_Packet (header) // and data so that they may be sent as a single packet. byte[] buffer = new byte[WP_Packet.packetSize + data.Length]; // Marshal the signature string into the buffer for (index = 0; index < packet.m_signature.Length && index < WP_Packet.m_crcHeader_offset; index++) { buffer[index] = (byte)packet.m_signature[index]; } while (index++ < WP_Packet.m_crcHeader_offset) buffer[index] = 0; // Fill to end with zeros // Marshal the WP_Packet (header) into the buffer. Note that the CRC values start as zero // so that the CRC of the WP_Packet (header) may be computed the same for host and target. WriteUINT32(buffer, WP_Packet.m_crcHeader_offset, 0); WriteUINT32(buffer, WP_Packet.m_crcData_offset, 0); WriteUINT32(buffer, WP_Packet.m_cmd_offset, (UInt32)packet.m_cmd); WriteUINT16(buffer, WP_Packet.m_seq_offset, packet.m_seq); WriteUINT16(buffer, WP_Packet.m_seqReply_offset, packet.m_seqReply); WriteUINT32(buffer, WP_Packet.m_flags_offset, packet.m_flags); WriteUINT32(buffer, WP_Packet.m_size_offset, (UInt32)data.Length); // Copy the data to the buffer for (int i = 0; i < data.Length; i++) buffer[WP_Packet.packetSize + i] = data[i]; // Calculate the CRC of the data if (data.Length != 0) { packet.m_crcData = SUPPORT_ComputeCRC(data, 0, data.Length, 0); WriteUINT32(buffer, WP_Packet.m_crcData_offset, packet.m_crcData); } // Calculate the CRC of the packet header packet.m_crcHeader = SUPPORT_ComputeCRC(buffer, 0, WP_Packet.packetSize, 0); WriteUINT32(buffer, WP_Packet.m_crcHeader_offset, packet.m_crcHeader); // Write out the complete packet to the USB stream stream.Write(buffer, 0, buffer.Length); }
// Check the given UsbStream for a valid WireProtocol packet (header). Returns true // along with the WP_Packet (header) if available. Returns false if nothing valid received as yet. public static bool ReadPacket(UsbStream stream, out WP_Packet packet) { packet = new WP_Packet(); byte[] buffer = new byte[WP_Packet.packetSize]; // Size of marshalled WP_Packet int nRead; // Read in enough data for a complete WP_Packet (header) nRead = stream.Read(buffer, 0, WP_Packet.packetSize); // If there were not enough bytes to fill the complete WP_Packet, it's no good if (nRead != WP_Packet.packetSize) { return false; } // Unmarshal the signature string from the buffer to the WP_Packet packet.m_signature = ""; for (int i = 0; (i < WP_Packet.m_crcHeader_offset) && (buffer[i] != 0); i++) { packet.m_signature += (char)buffer[i]; } // Unmarshal the rest of the buffer into the WP_Packet structure. packet.m_crcHeader = ReadUINT32(buffer, WP_Packet.m_crcHeader_offset); packet.m_crcData = ReadUINT32(buffer, WP_Packet.m_crcData_offset); packet.m_seq = ReadUINT16(buffer, WP_Packet.m_seq_offset); packet.m_seqReply = ReadUINT16(buffer, WP_Packet.m_seqReply_offset); packet.m_flags = ReadUINT32(buffer, WP_Packet.m_flags_offset); packet.m_size = ReadUINT32(buffer, WP_Packet.m_size_offset); packet.m_cmd = (Commands)ReadUINT32(buffer, WP_Packet.m_cmd_offset); // The header CRC must first be zeroed to calculate the correct header CRC WriteUINT32(buffer, WP_Packet.m_crcHeader_offset, 0); // If the calculated CRC does not match that of the packet, it is no good if (packet.m_crcHeader != SUPPORT_ComputeCRC(buffer, 0, WP_Packet.packetSize, 0)) { return false; } return true; }
static bool SendMouseReport(UsbStream stream, bool button1, bool button2, bool button3, byte Xmovement, byte Ymovement) { byte[] report = new byte[3]; report[0] = (byte)((button1 ? 1 : 0) | (button2 ? 2 : 0) | (button3 ? 4 : 0)); report[1] = Xmovement; report[2] = Ymovement; stream.Write(report, 0, 3); return true; }
// Accepts only a good packet. If the packet is a Ping, the Ping response (ACK) is sent. // Otherwise, the command is NAK'ed. static bool RespondToPacket(UsbStream pinger, WireProtocol.WP_Packet inPacket, UInt16 seq) { WireProtocol.WP_Packet outPacket = new WireProtocol.WP_Packet(); // Allocate space for any data following the packet int size = (int)(inPacket.m_size & 0xFFFF); byte[] buffer = new byte[size]; // Read in the data that came with the packet if (inPacket.m_size != 0) pinger.Read(buffer, 0, size); // Fill in the blanks of the response packet outPacket.m_signature = "MSdbgV1"; // Standard target signature outPacket.m_cmd = inPacket.m_cmd; // Show which command this is a response to outPacket.m_seq = seq++; // Keep track of the target message sequence number outPacket.m_seqReply = inPacket.m_seq; // Show which host packet sequence number this is a response to // If the host packet was a Ping if (inPacket.m_cmd == WireProtocol.Commands.Ping) { byte[] data = new byte[8]; // The Ping has an 8 byte data response outPacket.m_flags = 0x8003; // Return a low-priority ACK for (int i = 0; i < 8; i++) data[i] = 0; // Initialize all bytes of the data response to zero data[0] = 1; // This tells the host that we are TinyBooter data[4] = 2; // This is an innoccuous flag value WireProtocol.SendPacket(pinger, outPacket, data); // Send response to the Ping } else { outPacket.m_flags = 0x4003; // Return a low-priority NACK WireProtocol.SendPacket(pinger, outPacket, new byte[0]); // Signal to the host that we don't know what to do with the command } return true; }
static void PingerLoop(UsbStream pinger) { // Allocate in and out packets for "TinyBooter" simulation WireProtocol.WP_Packet inPacket; // Allocate packet for Pinger input UInt16 seq = 0; // Initialize Pinger packet sequence number // While the done button is not pressed while (buttons.done.Read()) { Thread.Sleep(10); // No need to respond in a hurry if (WireProtocol.ReadPacket(pinger, out inPacket)) { RespondToPacket(pinger, inPacket, seq); } } // Wait for the done button to be released while (!buttons.done.Read()) ; }
public static bool Init() { Cdc vsp = new Cdc(); //activedevice is null Controller.ActiveDevice = vsp; // Send "Hello world!" to PC every second. (Append a new line too) //byte[] bytes = System.Text.Encoding.UTF8.GetBytes("Hello world!\r\n"); while (true) { // Check if connected to PC if (Controller.State != UsbController.PortState.Running) { Debug.Print("Waiting to connect to PC..."); } else break; //else //{ // vsp.Stream.Write(bytes, 0, bytes.Length); //} Thread.Sleep(500); } // See if the hardware supports USB UsbController[] controllers = UsbController.GetControllers(); // Bail out if USB is not supported on this hardware! if (0 == controllers.Length) { Debug.Print("USB is not supported on this hardware!"); return false; } foreach (UsbController controller in controllers) { if (controller.Status != UsbController.PortState.Stopped) { controller.Stop(); Thread.Sleep(1000); } } // Find a free USB controller UsbController usbController = null; foreach (UsbController controller in controllers) { if (controller.Status == UsbController.PortState.Stopped) { usbController = controller; break; } } // If no free USB controller if (null == usbController) { Debug.Print("All available USB controllers already in use. Set the device to use Ethernet or Serial debugging."); return false; } try { // Configure the USB controller if (ConfigureUSBController(usbController)) { usbStream = usbController.CreateUsbStream(WRITE_EP, READ_EP); usbStream.ReadTimeout = 60000; usbStream.WriteTimeout = 60000; } else { throw new Exception(); } } catch (Exception) { Debug.Print("USB stream could not be created, error " + usbController.ConfigurationError.ToString()); return false; } return true; }
/// <summary> /// /// </summary> /// <param name="port"></param> /// <param name="mouse"></param> static void MouseLoop(UsbController port, UsbStream mouse) { // Mouse report storage. byte[] report = new byte[5]; // Offsets into mouse report storage. const byte BUTTONS = 0; const byte X_MOVEMENT = 1; const byte Y_MOVEMENT = 2; // Size of mouse movement for each report (every 10 mS). const byte mouseStep = 3; bool fAddMouse = true; // While the Done button is not pressed... while (buttons.Done.Read()) { // Perform this operation once every 10 milliseconds (actually a // bit more than 10 milliseconds). We've asked the host to // query for mouse info at least every 10 milliseconds, but it // actually queries every 8 milliseconds - it's OK not to // respond to every query. Thread.Sleep(10); report[X_MOVEMENT] = 0; // Zero X movement report[Y_MOVEMENT] = 0; // Zero Y movement // Add X,Y movement to the mouse report. if (!buttons.Left.Read()) report[X_MOVEMENT] -= mouseStep; if (!buttons.Right.Read()) report[X_MOVEMENT] += mouseStep; if (!buttons.Up.Read()) report[Y_MOVEMENT] -= mouseStep; if (!buttons.Down.Read()) report[Y_MOVEMENT] += mouseStep; if (!buttons.Toggle.Read()) { if (mouse != null) { mouse.Dispose(); mouse = null; } fAddMouse = !fAddMouse; ConfigureUsbPort(port, fAddMouse); if (fAddMouse) { mouse = port.CreateUsbStream(3, UsbStream.NullEndpoint); } } // Add the button state to the mouse report. report[BUTTONS] = (byte)((!buttons.LeftMouseButton.Read() ? 1 : 0) | (!buttons.RightMouseButton.Read() ? 2 : 0)); if (mouse != null) { // Send the mouse report to the host. mouse.Write(report, 0, 3); } } // Wait for the Done button to be released. while (!buttons.Done.Read()) ; }
public UsbStream CreateUsbStream(int writeEndpoint, int readEndpoint) { UsbStream s = null; lock (s_openStreams) { if (s_openStreams[m_controllerIndex] == null) { s_openStreams[m_controllerIndex] = new ArrayList(); } ArrayList streams = (ArrayList)s_openStreams[m_controllerIndex]; // if this is the first UsbStream associated with this controller, then start the controller if (streams.Count == 0) { // UsbController.GetController(m_controllerIndex).Start(); Start(); } try { s = new UsbStream(m_controllerIndex, writeEndpoint, readEndpoint); } catch (Exception e) { Stop(); throw e; } streams.Add(s); } return s; }