// Socket Read Callback (JNW Jan15) public void myReadCallBack(IAsyncResult ar) { NetworkStream myNetworkStream = (NetworkStream)ar.AsyncState; int count = 0; if (runFlag == false || myNetworkStream.CanRead == false) // Socket Closed? { return; } try { count = myNetworkStream.EndRead(ar); if (!receivePortDataQueue.Enqueue((Object)(Support.PackByte(myReadBuffer, 0, count)))) { // Inbound Queue is full, so just drop the packet... c'est la vie. Support.DbgPrint("dropped inbound bytes. Count = " + count.ToString()); _inboundQueueErrorCount++; } myNetworkStream.BeginRead(myReadBuffer, 0, myReadBuffer.Length, new AsyncCallback(myReadCallBack), myNetworkStream); } catch (Exception ex) { Support.DbgPrint("Exception during tcp port read. Ex: " + ex.Message); } }
// Socket Read Callback (JNW Jan15) public void myReadCallBack(int count) { if (runFlag == false || count == 0) // Socket Closed? { return; } try { if (!receivePortDataQueue.Enqueue((Object)(Support.PackByte(myReadBuffer, 0, count)))) { // Inbound Queue is full, so just drop the packet... c'est la vie. Support.DbgPrint("dropped inbound bytes. Count = " + count.ToString()); _inboundQueueErrorCount++; } Task.Run(() => { var count = netStream.Read(myReadBuffer, 0, myReadBuffer.Length); myReadCallBack(count); }); } catch (Exception ex) { Support.DbgPrint("Exception during tcp port read. Ex: " + ex.Message); } }
// // COM port read event handler delegate // void SerialPortRead() { Byte[] tmpBuf = new Byte[2048]; Int32 count; try { count = port.BaseStream.Read(tmpBuf, 0, tmpBuf.Length); if (!receivePortDataQueue.Enqueue((Object)(Support.PackByte(tmpBuf, 0, count)))) { // Inbound Queue is full, so just drop the packet... c'est la vie. Support.DbgPrint("dropped inbound bytes. Count = " + count.ToString()); _inboundQueueErrorCount++; } if (runFlag) { Task.Run(() => { SerialPortRead(); }); } } catch (Exception ex) { Support.DbgPrint("Exception during serial port read. Ex: " + ex.Message); } }
// // COM port read event handler delegate // void SerialPortRead(Object sender, SerialDataReceivedEventArgs e) { Byte[] tmpBuf = new Byte[2048]; Int32 numBytes; Int32 count; try { while (runFlag && ((numBytes = port.BytesToRead) > 0)) { if (numBytes > tmpBuf.Length) { numBytes = tmpBuf.Length; } count = port.Read(tmpBuf, 0, numBytes); if (!receivePortDataQueue.Enqueue((Object)(Support.PackByte(tmpBuf, 0, count)))) { // Inbound Queue is full, so just drop the packet... c'est la vie. Support.DbgPrint("dropped inbound bytes. Count = " + count.ToString()); _inboundQueueErrorCount++; } } } catch (Exception ex) { Support.DbgPrint("Exception during serial port read. Ex: " + ex.Message); } }
public void Start() { lock (syncLock) { timerT.Start(); } Support.DbgPrint("Timer " + tName + " Started"); }
public void Restart() { lock (syncLock) { Stop(); Start(); } Support.DbgPrint("Timer " + tName + " Restarted"); }
// // Beacon timeout handler // void timerBeacon_Elapsed(object sender, ElapsedEventArgs e) { if (beaconEnable) { Support.DbgPrint("Beacon timer fired..."); SendDatagram(beaconDestination, beaconRelay1, beaconRelay2, Encoding.ASCII.GetBytes(beaconText)); } else { timerBeacon.Stop(); } }
public void SetTime(Int32 time, Boolean variable) { if (variable) { // // Add up to an attitional 50% to the time value to help avoid channel collisions // time += timeRandom.Next(time >> 1); } Support.DbgPrint("Timer " + tName + " interval set to msec: " + time.ToString()); timerT.Interval = Convert.ToDouble(time); }
// // Decode the received frame // Boolean Decode(out String packetFrame) { Int32 ptr = 0; Boolean retVal = false; StringBuilder s = new StringBuilder("|", 4096); try { // // Catch any exceptions during decode // ptr = staLink.destinationStation.Decode(inBuf, ptr); ptr = staLink.sourceStation.Decode(inBuf, ptr); s.Append("|" + staLink.sourceStation.stationIDString + "|ch=" + staLink.sourceStation.chBit.ToString()); s.Append("|" + staLink.destinationStation.stationIDString + "|ch=" + staLink.destinationStation.chBit.ToString()); if (staLink.sourceStation.extBit == 0) { ptr = staLink.relayStation1.Decode(inBuf, ptr); s.Append("|" + staLink.relayStation1.stationIDString + "|ch=" + staLink.relayStation1.chBit.ToString()); if (staLink.relayStation1.extBit == 0) { ptr = staLink.relayStation2.Decode(inBuf, ptr); s.Append("|" + staLink.relayStation2.stationIDString + "|ch=" + staLink.relayStation2.chBit.ToString()); if (staLink.relayStation2.extBit == 0) { StationAddress tmpR = new StationAddress(); s.Append("|r??:("); do { ptr = tmpR.Decode(inBuf, ptr); s.Append("\\" + tmpR.stationIDString + ":ch=" + tmpR.chBit.ToString()); } while (tmpR.extBit == 0); s.Append(")"); //throw new Exception("Too many relay addresses"); } else { s.Append("|"); } } else { s.Append("||"); } } else { s.Append("|||"); } cmdOctetPtr = ptr; if ((staLink.destinationStation.chBit == staLink.sourceStation.chBit)) { // // Old protocol version // version = ProtocolVersion.V20; } else { // // New protocol version // version = ProtocolVersion.V22; } if (staLink.destinationStation.chBit == 0) { // // Response type // cmdResp = PacketType.Response; } else { // // Command type // cmdResp = PacketType.Command; } // // Get frame type. I and S frame must be decoded later after we know whether we // are using mod8 or mod128 sequence numbers. // Byte tmp = inBuf[ptr]; String t = ""; pfBit = (tmp >> 4) & 0x01; //ToDo change needed to support SABME seqNumMode = SequenceNumberMode.Mod8; //Frame.InformationFrame.Decode(this, rawBuf, ptr, out t); if ((tmp & 0x01) == I) { // // I frame // frameClass = FrameClasses.IClass; frameType = FrameTypes.IType; ptr = InformationFrame.Decode(this, inBuf, ptr, out t); } if ((tmp & 0x03) == S) { // // S frame // frameClass = FrameClasses.SClass; frameType = (FrameTypes)(tmp & 0x0f); ptr = SupervisoryFrame.Decode(this, inBuf, ptr, out t); } if ((tmp & 0x03) == U) { // // U frame. We can decode uFrames right away // frameClass = FrameClasses.UClass; frameType = (FrameTypes)(tmp & 0xef); ptr = UnnumberedFrame.Decode(this, inBuf, ptr, out t); } s.Append("|" + version.ToString() + "|" + frameType.ToString() + "|" + cmdResp.ToString() + "|pf=" + pfBit.ToString()); if (t.Length > 0) { s.Append(t); } s.Append(Support.DumpRawFrame(rawBuf)); retVal = true; } catch (Exception ex) { s.Append(ex.Message + CRLF); Support.DbgPrint("Exception during frame decode:" + ex.Message + CRLF); retVal = false; } finally { s.Append("]"); packetFrame = s.ToString(); } return(retVal); }
// // Segmenter timeout handler // void timerSegmenter_Elapsed(object sender, ElapsedEventArgs e) { Support.DbgPrint("Segmenter timer fired..."); recvDatagramQ.Wakeup(); timerSegmenter.Stop(); }
// // Link Test timeout handler // void timerTestCommandTimeout_Elapsed(object sender, ElapsedEventArgs e) { Support.DbgPrint("TestCommandTimeout timer fired..."); linkTestQ.Wakeup(); timerTestCommandTimeout.Stop(); }
void ProcessDLPackets() { Frame.Packet packet; Connection con; Int32 tmpL = 4; Support.DbgPrint(Thread.CurrentThread.Name + " Starting..."); while (runFlag) { // // This thread get incoming packets from the remote and sends them off for procesing // try { packet = (Frame.Packet)dataLinkProviderQ.Dequeue(); } catch { continue; } if (packet == null) { continue; } if (packet.transmitFrame != null) { // // Incoming packets are passed in as transmit frames and are sent out to the TNC Channel // _localTncChannel.Send(packet.transmitFrame); } else { // // Packets arriving from lower layer come in as received frames // if (packet.receivedFrame.decodeOK) { // // Process the parsed frame // Int32 pfBit = packet.receivedFrame.pfBit; // // Unnumbered frame // if (packet.receivedFrame.frameType.Equals(Frame.FrameTypes.UIType)) { // // Unnumbered Info Frame received, so pop it into the DLP Recv datagram Q // code falls through and Sends DM resp if PFBit is set // recvDatagramQ.Enqueue(packet.receivedFrame.iBuf); if (pfBit == 0) { continue; } } if (packet.receivedFrame.frameType.Equals(Frame.FrameTypes.TESTType)) { // // Test frame // if (packet.receivedFrame.cmdResp.Equals(Frame.PacketType.Command)) { Int32 i; Int32 f = tmpR.Length >> 1; // // Send out a response to in incoming test command // Byte[] tBuf = new Byte[f + packet.receivedFrame.iBuf.Length]; for (i = 0; i < f; i++) { tBuf[i] = (Byte)(tmpR[i / tmpL, i % tmpL] ^ tmpR[(i + f) / tmpL, i % tmpL]); } packet.receivedFrame.iBuf.CopyTo(tBuf, i); Frame.Packet tmpP = new Frame.Packet( Frame.TransmitFrameBuild(packet.receivedFrame.staLink.Rev(), Station.CommandResponse.DoResponse, pfBit, Frame.FrameTypes.TESTType, tBuf)); dataLinkProviderQ.Enqueue(tmpP); } else { // // Test resp received. Return buffer to upper layer // linkTestQ.Enqueue(packet.receivedFrame.iBuf); } continue; } // // Other packet types get sent to the upper layer (If one is available) // con = GetConnection(packet.receivedFrame.staLink.GetConnectionPathRev()); if (con == null) { // // No existing connection available, so check for any listeners // con = GetAvailableConnection(packet.receivedFrame.staLink.destinationStation.stationIDString); if (con != null) { // // Found a listener, so set up the connection // con.connectedStation.destinationStation.SetCallSign(packet.receivedFrame.staLink.sourceStation.stationIDString); if (packet.receivedFrame.staLink.relayStation2.stationIDString.Length > 0) { con.connectedStation.relayStation1.SetCallSign(packet.receivedFrame.staLink.relayStation2.stationIDString); con.connectedStation.relayStation2.SetCallSign(packet.receivedFrame.staLink.relayStation1.stationIDString); } else if (packet.receivedFrame.staLink.relayStation1.stationIDString.Length > 0) { con.connectedStation.relayStation1.SetCallSign(packet.receivedFrame.staLink.relayStation1.stationIDString); } } else { // // No connection so send DM resp with PF bit set to uframe.pfBit // _localTncChannel.Send(Frame.TransmitFrameBuild(packet.receivedFrame.staLink.Rev(), Station.CommandResponse.DoResponse, pfBit, Frame.FrameTypes.DMType, null).ibuf); continue; } } // // Found a connection, so sent the packet off to it // con.Insert(packet); continue; } // // Arrival here means the frame did not decode correctly, so just drop the packet // Support.DbgPrint(Thread.CurrentThread.Name + " - Frame decode error"); } } Support.DbgPrint(Thread.CurrentThread.Name + " exiting..."); }
public void Stop() { timerT.Stop(); Support.DbgPrint("Timer " + tName + " Stopped"); }
public void Start() { Support.DbgPrint("Timer " + tName + " Started"); timerT.Start(); }
// // Com port send thread // void sendToPort() { KissBuf kBuf = null; Byte[] tmpB = new Byte[MAXBUF]; Byte[] buf; Int32 count = 0; Support.DbgPrint(Thread.CurrentThread.Name + " starting"); while (runFlag) /* 1/22/2015 W4PHS */ { // // COM port send process loop // try { kBuf = (KissBuf)sendQ.Dequeue(); if (kBuf == null) { continue; } } catch { Support.DbgPrint(Thread.CurrentThread.Name + " sendQ.Dequeue Exception"); continue; } // // Add Framing character and channel/command information to the start of the buffer // count = 0; tmpB[count++] = FEND; // If Ackmode specified, send Header (JNW Jan15) if (kBuf.Frame != null) { // Ackmode FOrmat // See if Acxkmode Needed buf = kBuf.Frame.ibuf; if (kBuf.Frame.AckModeID != 0) { tmpB[count++] = (Byte)((kBuf.chan << 4) | 0x0c); tmpB[count++] = (Byte)(kBuf.Frame.AckModeID >> 8); tmpB[count++] = (Byte)(kBuf.Frame.AckModeID & 0xff); } else { tmpB[count++] = (Byte)((kBuf.chan << 4) | kBuf.cmd); } } else { // Old (Non-AckMode) format buf = kBuf.buf; if (kBuf.cmd == 0x0f) { tmpB[count++] = 0xff; // Kiss Mode off } else { tmpB[count++] = (Byte)((kBuf.chan << 4) | kBuf.cmd); } } if (kBuf.cmd != 0x0f) { // // PRW change 10/10/2010 - Move the fill buffer code inside the else clause. Otherwise our kiss exit // sequence ended up being: C0 FF 00 C0 rather than the correct value of: C0 FF C0 // foreach (Byte b in buf) { // // In addition to escaping the normal FEND & FESC bytes, we will also // insert a dummy escape sequence for Capital C. This will break up the string "TC 0 <CR>" that // screws up the D710 TNC while in KISS mode. Since it is an invalid escape, it should be discarded // at the remote end. // if (Escaped(b)) { // // This byte is on the list of characters to escape // tmpB[count++] = FESC; } if ((b == FEND) || (b == FESC)) { if (b == FEND) { tmpB[count++] = FESC; tmpB[count++] = TFEND; } if (b == FESC) { tmpB[count++] = FESC; tmpB[count++] = TFESC; } } else { tmpB[count++] = b; } } } tmpB[count++] = FEND; try { if (loopBackMode) { // Send data back to receive port if (!receivePortDataQueue.Enqueue((Object)Support.PackByte(tmpB, 0, count))) { // Inbound Queue is full, so just drop the packet... c'est la vie. _inboundQueueErrorCount++; } } else { if (TCPMode) { netStream.Write(tmpB, 0, count); } else { port.Write(tmpB, 0, count); } } } catch { } // Close if connection lost if (TCPMode) { runFlag = client.Connected; } else { runFlag = port.IsOpen; /* 1/22/2015 W4PHS */ } } Support.DbgPrint(Thread.CurrentThread.Name + " exit"); }
//#endregion //#region COM port communication thread routines // // COM port receive thread // private void recvFromPort() { Boolean inFrame = false; Boolean doUnescape = false; Boolean gotChannel = false; Byte[] rcvBuf = new Byte[MAXBUF]; Byte[] portBuf; Int32 count = 0; Int32 channel = 0; Int32 command = 0; // KISS Command Byte (JNW Jan15) Support.DbgPrint(Thread.CurrentThread.Name + " starting"); while (runFlag) { // // COM port receive process loop // try { portBuf = (Byte[])receivePortDataQueue.Dequeue(); if (portBuf == null) { // Loop if null buffer. continue; } } catch { // Loop if we get an exception continue; } foreach (byte tmp in portBuf) { if (inFrame) { // // In a frame // if (doUnescape) { // // Process escaped characters // Characters other than TFEND and TFESC are discarded // if (tmp == TFEND) { rcvBuf[count++] = FEND; } else if (tmp == TFESC) { rcvBuf[count++] = FESC; } else { // // Ignore the FESC character for other characters. // rcvBuf[count++] = tmp; } doUnescape = false; continue; } if (tmp == FESC) { // Process next character as escaped doUnescape = true; continue; } if (tmp == FEND) { if (!gotChannel) { // // looks like back-to-back FEND characters, // so bump the frame error count and keep going // //_KISSFrameErrorCount++; continue; } if (count > 0) { // // End of frame, so send up the packet // if (recvQs[channel] == null) { // Bad channel received _KISSFrameErrorCount++; } else { if (!recvQs[channel].Enqueue((object)Support.PackByte(rcvBuf, 0, count))) { // Inbound Queue is full, so just drop the packet... c'est la vie. _inboundQueueErrorCount++; } } } count = 0; // Reset buffer len inFrame = true; // Set to True to handle the case where the same FEND byte is used for both end and start gotChannel = false; continue; } if (count >= MAXBUF) { // // Strange happenings on the channel. Frame should // never get this big. Reset & continue. // _KISSFrameErrorCount++; count = 0; inFrame = false; gotChannel = false; continue; } if (!gotChannel) { // // Get channel # from upper nibble of first byte // command = tmp & 0x0f; // Extract Command Byte (JNW Jan15) channel = Convert.ToInt32(tmp >> 4); gotChannel = true; continue; } rcvBuf[count++] = tmp; // Normal character } else { // Not in a frame. Ignore all but FEND if (tmp == FEND) { // // Start of frame // inFrame = true; } } } } Support.DbgPrint(Thread.CurrentThread.Name + " exit"); }
// // Public methods // //public void COMPortInit(String comPort, Int32 baud) //{ // COMPortInit(comPort, baud, false); //} void COMPortInit(String comPort, Int32 baud, Boolean loopback, String Host, Int32 Port, SerialPort sPort) // JNW Apr15 { // // Initialization // loopBackMode = loopback; receivePortDataQueue = new BlockingQueue(MAXQUEUESIZE); // Port level receive queue sendQ = new BlockingQueue(MAXQUEUESIZE); // packet level send queue for all channels if (comPort != null && comPort.Equals("TCP")) { TCPMode = true; TCPPort = Port; // JNW Apr15 TCPHost = Host; } else { TCPMode = false; } if (TCPMode) { try { client = new TcpClient(TCPHost, TCPPort); netStream = client.GetStream(); // This will run in the background. Task.Run(() => { var count = netStream.Read(myReadBuffer, 0, myReadBuffer.Length); myReadCallBack(count); }); } catch (Exception ex) { Support.DbgPrint("TCP Connect Failed. Ex: " + ex.Message); } } else { if (sPort == null) { port = new SerialPort(comPort, baud, Parity.None, 8, StopBits.One); // No flow control. Upper AX.25 layer handles dropped data port.Handshake = Handshake.None; port.RtsEnable = true; } else { // Flow control was initialized already, so no need to do it again. port = sPort; } if (!loopBackMode) // We don't use the serial port in loopback mode { // Add the read event handler //comHandler = new SerialDataReceivedEventHandler(SerialPortRead); //port.DataReceived += comHandler; if (sPort == null) { port.Open(); } //port.ReadTimeout = 1; port.DiscardInBuffer(); Task.Run(() => { SerialPortRead(); }); } } if (client != null || port != null) { recvThread = new Thread(recvFromPort); // Threads handle com port I/O recvThread.Name = "ComPort Receive Thread for Port: " + comPort; sendThread = new Thread(sendToPort); sendThread.Name = "ComPort Transmit Thread for Port: " + comPort; recvThread.Start(); // Light 'em up sendThread.Start(); } }
public void Restart() { Support.DbgPrint("Timer " + tName + " Restarted"); Stop(); Start(); }
// // Procesing thread for incoming packets from the TNC. The TNC places a buffer // containing the incoming data into the channel's receive queue. This routine pulls // these frames from the queue for processing. // // Processing steps: // - Parse the raw incoming frame into a receive buffer. // - Find the Data Link Provider handling incoming data for the Station ID // specified in the incoming address field of the packet. If no matching // dlp is registered, then we simply drop the packet. (Future: we add in support // for multi-cast packets, which will forward to all registered DLPs) // - Place the frame, source, and buffer type into a packet object and place it into the // receive queue of the target DLP. // void RecvFromPort() { String parsedFrameString = ""; Byte[] buf; Support.DbgPrint(Thread.CurrentThread.Name + "Starting."); while (runFlag && comSerialPort.Enabled) { try { buf = Recv(); } catch { continue; } if (buf == null) { continue; } // check for ACKMODE Response (Need to be at channel level to find DLC) (JNW Jan15) if (buf.Length == 2) // Only ACK frames are this short { Int16 AckID = (Int16)(buf[0] << 8 | buf[1]); Connection con; lock (dataLinkProviderList) foreach (DataLinkProvider dlp in dataLinkProviderList) { con = GetConnectionByACKModeID(dlp, AckID); if (con != null) { // Set Timer back to normal con.timerAck.SetTime(con.smoothedRoundTrip, true); break; } } continue; // Donf pass Ack frame up to next level } // // Parse raw buffer // Frame.ReceivedFrame pFrame = new Frame.ReceivedFrame(buf, out parsedFrameString); // // Output to monitor queue is enabled // if (!_packetMonitorEnable.Equals(PacketMonitorType.None)) { StringBuilder frameString = new StringBuilder("|chan:" + chanNum.ToString() + "|<--", 4096); frameString.Append(parsedFrameString); if (_packetMonitorEnable.Equals(PacketMonitorType.LogFile) || _packetMonitorEnable.Equals(PacketMonitorType.Both)) { Support.PktPrint(frameString.ToString() + CRLF, ref packetLogSyncObject); } if (_packetMonitorEnable.Equals(PacketMonitorType.Queue) || _packetMonitorEnable.Equals(PacketMonitorType.Both)) { packetMonitorQueue.Enqueue(frameString.ToString()); } } Frame.Packet packet = new Frame.Packet(pFrame); DigipeatCheckAndProcess(packet); //continue; // // Send up to the data link provider handling the specified StationID // //dlp.Send(packet); } Support.DbgPrint(Thread.CurrentThread.Name + "Exiting."); }