/// <summary> /// Main thread function /// </summary> public void Run() { bool event_occured; DateTime last_device_open_timestamp = DateTime.Now; // communication loop while (!m_stop_requested) { // wait for event event_occured = m_thread_event.WaitOne(ThreadWaitTimeout); // exit loop if thread must be stopped if (m_stop_requested) { break; } // try to open device if it is not opened if (m_device_handle == null || m_device_handle.IsClosed) { // device is not opened -> try to open it if ((DateTime.Now - last_device_open_timestamp).TotalMilliseconds > DeviceOpenRetryPeriod) { // enumerate devices List <DeviceInfo> device_info = EnumerateDevices(); // TODO: do device selection if (device_info.Count > 0) { if (Open(device_info[0].DevicePath)) { // reserve report buffers m_input_report_buffer = new byte[m_input_report_length]; // prepare for packet receiving m_received_packet_pos = 0; m_received_packet_length = 0; m_transmitter_locked = TransmitterFree; StartReading(); } } } } else { // device is opened // process incoming packets if (m_received_packet_length > 0) { if (m_received_packet_length <= PacketConstants.PacketMaxLength) { m_communication_manager.StoreReceivedPacket(m_communication_channel_index, m_receive_packet_buffer, (byte)m_received_packet_length); } // restart packet reading m_received_packet_length = 0; m_received_packet_pos = 0; StartReading(); } } } // close USB device Close(); // thread is finished m_thread_stopped.Set(); }
/// <summary> /// Main thread function /// </summary> public void Run() { bool event_occured; int i; UInt16 crc; AsyncCallback receiver_callback = new AsyncCallback(ReceiveCallback); // create endpoints m_receiver_endpoint = new IPEndPoint(IPAddress.Any, UDPLocalPort); // init socket m_timestamp = DateTime.MinValue; m_client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); m_client.Blocking = false; m_client.EnableBroadcast = true; m_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); m_client.Bind(m_receiver_endpoint); // init m_upstream_bytes = 0; m_downstream_bytes = 0; // start data reception m_client.BeginReceive(m_receive_buffer, 0, m_receive_buffer.Length, 0, receiver_callback, this); // communication loop while (!m_stop_requested) { // wait for event event_occured = m_thread_event.WaitOne(ThreadWaitTimeout); // exit loop if thread must be stopped if (m_stop_requested) { break; } // process received data if (m_received_data_length > 0) { if (m_received_data_length > 2) { // check CRC crc = CRC16.CalculateForBlock(CRC16.InitValue, m_receive_buffer, m_received_data_length - 2); if (ByteAccess.LowByte(crc) == m_receive_buffer[m_received_data_length - 2] && ByteAccess.HighByte(crc) == m_receive_buffer[m_received_data_length - 1]) { // CRC OK -> continue processing received packet PacketType type = (PacketType)m_receive_buffer[PacketConstants.TypeOffset]; // update statistics Interlocked.Add(ref m_upstream_bytes, m_received_data_length); // process received packet switch (type) { // process device annnounce packet case PacketType.CommDeviceAnnounce: { PacketDeviceAnnounce device_info; // get announce packet device_info = (PacketDeviceAnnounce)RawBinarySerialization.DeserializeObject(m_receive_buffer, typeof(PacketDeviceAnnounce)); // check if it is already on the list of active devices DeviceInfo current_device_info = m_detected_devices.Find(x => x.UniqueID == device_info.UniqueID); if (current_device_info != null) { // device is on the list current_device_info.HostAnnouncePending = true; current_device_info.LastInfoTimestamp = DateTime.Now; } else { DeviceInfo new_device = new DeviceInfo(device_info); new_device.HostAnnouncePending = true; if (new_device.Address != IPAddress.None) { m_detected_devices.Add(new_device); if (m_detected_devices.Count == 1) { lock (m_detected_devices) { m_current_device = m_detected_devices[0]; } } } } } break; default: // process received data if (m_received_data_length <= PacketConstants.PacketMaxLength) { m_communication_manager.StoreReceivedPacket(m_communication_channel_index, m_receive_buffer, (byte)m_received_data_length); } break; } } } // restart reception try { m_received_data_length = 0; m_client.BeginReceive(m_receive_buffer, 0, m_receive_buffer.Length, 0, receiver_callback, this); } catch { // TODO: error handling } } // send host announce for devices for (i = 0; i < m_detected_devices.Count; i++) { IPAddress address_mask = new IPAddress(new byte[] { 255, 255, 255, 0 }); if (m_detected_devices[i].HostAnnouncePending) { IPAddress local_ip = GetLocalIPAddress(m_detected_devices[i].Address, address_mask); if (m_sender_lock.Wait(0)) { // create host info packet PacketHostAnnounce info = new PacketHostAnnounce(); info.Address = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(local_ip.GetAddressBytes(), 0)); byte[] packet = RawBinarySerialization.SerializeObject(info); // send host info packet EndPoint transmitter_endpoint = new IPEndPoint(m_detected_devices[i].Address, UDPRemotePort); InternalPacketSend(transmitter_endpoint, packet); m_detected_devices[i].HostAnnouncePending = false; } } } // delete unreachable or connectecd devices from the list DateTime current_timestamp = DateTime.Now; i = 0; while (i < m_detected_devices.Count) { // if devlice is silent for a while -> remove from the list if ((current_timestamp - m_detected_devices[i].LastInfoTimestamp).TotalMilliseconds > DeviceAnnounceTimeout) { m_detected_devices.RemoveAt(i); } else { i++; } } } // close socket m_client.Shutdown(SocketShutdown.Both); Thread.Sleep(10); m_client.Close(); // thread is finished m_thread_stopped.Set(); }
/// <summary> /// Main thread function /// </summary> public void Run() { bool event_occured; UInt16 crc; int received_data_pos; int received_packet_pos; // init SLIPs m_receiver_slip.ResetDecoder(); try { m_serial_port = new SerialPort(PortName, BaudRate, Parity.None, 8, StopBits.One); m_serial_port.ReadTimeout = 50; m_serial_port.WriteTimeout = 50; m_serial_port.ReadBufferSize = 4096; m_serial_port.Open(); } catch { return; } // init m_upstream_bytes = 0; m_downstream_bytes = 0; received_data_pos = 0; received_packet_pos = 0; // start data reception m_read_pending = true; m_serial_port.BaseStream.BeginRead(m_receive_data_buffer, 0, m_receive_data_buffer.Length, m_receiver_callback, this); // communication loop while (!m_stop_requested) { // wait for event event_occured = m_thread_event.WaitOne(ThreadWaitTimeout); // exit loop if thread must be stopped if (m_stop_requested) { break; } // process received data if (m_received_data_length > 0) { received_data_pos = 0; while (received_data_pos < m_received_data_length) { // SLIP decode data if (m_receiver_slip.DecodeBlock(m_receive_data_buffer, ref received_data_pos, m_received_data_length, m_receive_packet_buffer, ref received_packet_pos)) { // packet decoded -> check CRC if (received_packet_pos > (Marshal.SizeOf(typeof(PacketBase)) + PacketConstants.PacketCRCLength)) { m_received_packet_length = received_packet_pos; crc = CRC16.CalculateForBlock(CRC16.InitValue, m_receive_packet_buffer, m_received_packet_length - PacketConstants.PacketCRCLength); if (ByteAccess.LowByte(crc) == m_receive_packet_buffer[m_received_packet_length - 2] && ByteAccess.HighByte(crc) == m_receive_packet_buffer[m_received_packet_length - 1]) { // CRC OK -> continue processing received packet PacketType type = (PacketType)m_receive_data_buffer[PacketConstants.TypeOffset]; // update statistics Interlocked.Add(ref m_upstream_bytes, m_received_data_length); // process received data if (m_received_packet_length <= PacketConstants.PacketMaxLength) { m_communication_manager.StoreReceivedPacket(m_communication_channel_index, m_receive_packet_buffer, (byte)m_received_packet_length); } } } // restart packet decoding received_packet_pos = 0; } m_read_pending = false; } } // restart reception if (!m_read_pending) { try { m_received_data_length = 0; m_read_pending = true; m_serial_port.BaseStream.BeginRead(m_receive_data_buffer, 0, m_receive_data_buffer.Length, m_receiver_callback, this); } catch { // stop thread because of the unexpected error m_stop_requested = true; m_thread_event.Set(); } } } // close socket m_serial_port.Close(); m_serial_port = null; // thread is finished m_thread_stopped.Set(); }