public AdvCANIO( ) { hDevice = INVALID_HANDLE_VALUE; lpCommandBuffer = Marshal.AllocHGlobal(AdvCan.CAN_COMMAND_LENGTH); lpConfigBuffer = Marshal.AllocHGlobal(AdvCan.CAN_CONFIG_LENGTH); lpStatusBuffer = Marshal.AllocHGlobal(AdvCan.CAN_CANSTATUS_LENGTH); lpEventCode = Marshal.AllocHGlobal(Marshal.SizeOf(EventCode)); Marshal.StructureToPtr(EventCode, lpEventCode, true); this.ioctlEvent = new ManualResetEvent(false); this.ioctlOvr = new Win32Ovrlap(this.ioctlEvent.SafeWaitHandle.DangerousGetHandle()); this.writeEvent = new ManualResetEvent(false); this.txOvr = new Win32Ovrlap(this.writeEvent.SafeWaitHandle.DangerousGetHandle()); readEvent = new AutoResetEvent(false); this.rxOvr = new Win32Ovrlap(readEvent.SafeWaitHandle.DangerousGetHandle()); this.eventOvr = new Win32Ovrlap(readEvent.SafeWaitHandle.DangerousGetHandle()); this.events = new Win32Events(this.eventOvr.memPtr); }
/// <summary> /// Main receiver thread for this com port instance. /// </summary> private void ReceiveThread() { // Create locals. uint firedEvent = 0; uint nBytes = 0; byte[] buf = new Byte[1]; // Create thread signal (initial state is non-signaled). AutoResetEvent signal = new AutoResetEvent(false); // Create overlap memory pointer. Install signal. this.rxOvr = new Win32Ovrlap(port.Handle, signal.Handle); // Instantiate the event class. this.events = new Win32Events(rxOvr.MemPtr); // Instantiate the modem signal class. this.modem = new Win32Modem(); // Set initial modem signal states. this.Signals(); // Signal the main thread that // the receive thread is started. this.recvrEvent.Set(); try { while(true) { // Arm the event monitoring mask. // if(this.events.Set(this.port.Handle, Win32Events.EV_DEFAULT)) if(this.events.Set(this.port.Handle, Win32Events.EV_TXEMPTY)) { // Wait for any armed event to occur. this.events.Wait(this.port.Handle, signal); // Get mask of fired events. firedEvent = this.events.GetMask; // Error event (override). if((firedEvent & Win32Events.EV_ERR) != 0) { if(this.stats.Reset(this.port.Handle) == false) { if(this.stats.Status == Win32Status.CE_BREAK) { firedEvent &= ~Win32Events.EV_BREAK; } else { this.CommError(this.stats.Fault); } } } else { // Receive event (override). if(((firedEvent & Win32Events.EV_RXCHAR) != 0) && (this.immediate)) { do { nBytes = 0; if(this.port.Read(buf, 1, out nBytes, this.rxOvr.MemPtr)) { if(nBytes == 1) this.OnRxChar(buf); } } while(nBytes > 0); } // TX queue empty event (override). if((firedEvent & Win32Events.EV_TXEMPTY) != 0) this.OnTxDone(); // Line break event (override). if((firedEvent & Win32Events.EV_BREAK) != 0) this.OnBreak(); // Modem signal change event(s) (override). if((firedEvent & Win32Events.EV_MODEM) > 0) { this.modem.Get(this.port.Handle); if((firedEvent & Win32Events.EV_CTS) > 0) this.OnCTS(this.modem.CtsState); if((firedEvent & Win32Events.EV_DSR) > 0) this.OnDSR(this.modem.DsrState); if((firedEvent & Win32Events.EV_RLSD) > 0) this.OnRLSD(this.modem.RlsdState); if((firedEvent & Win32Events.EV_RING) > 0) this.OnRING(this.modem.RingState); } } } } } catch(Exception e) { if((e is ThreadAbortException)) { this.modem = null; this.events = null; this.rxOvr = null; } else { this.CommError("Receiver Exception: " + e.Message); } } }