// 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); } }
// 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); } }
public static Int32 Decode(ReceivedFrame frame, Byte[] buf, Int32 ptr, out String s) { String r = ""; s = ""; ptr++; if (frame.frameType.Equals(FrameTypes.UIType)) { frame.pidInfo = new PidInfo(); ptr = frame.pidInfo.Decode(buf, ptr, out r); if (frame.pidInfo.cmdDecode.Equals(PidInfo.CommandDecode.Standard)) { // // On standard PID fields, pre-load the segmentation chuck data where the PID used to be in the buffer. // Extended info will already have the correct segmentation chunk info there. // buf[ptr] = Segmenter.StartOfSegment; } frame.iBuf = Support.PackByte(buf, ptr, (buf.Length - ptr)); s = r + "|||len:" + frame.iBuf.Length.ToString() + "|txt:(" + Support.GetString(frame.iBuf) + ")"; } if (frame.frameType == FrameTypes.TESTType) { frame.iBuf = Support.PackByte(buf, ptr, (buf.Length - ptr)); } if (frame.frameType == FrameTypes.XIDType) { XIDInfo xidInfo = new XIDInfo(); ptr = xidInfo.Decode(buf, ptr, out r); s = r; frame.xidFrame = xidInfo; } return(ptr); }
public static Int32 Decode(ReceivedFrame frame, Byte[] buf, Int32 ptr, out String s) { String r; //if (seqNumMode.Equals(SequenceNumberMode.Mod8)) //{ frame.numS = (buf[ptr] >> 1) & 0x07; frame.numR = (buf[ptr++] >> 5) & 0x07; // NumR = (buf[ptr++] >> 5) & 0x07; //} //else //{ // NumS = (buf[ptr++] >> 1) & 0x7f; // PFBit = buf[ptr] & 0x01; // NumR = (buf[ptr++] >> 1) & 0x7f; //} s = "|ns=" + frame.numS.ToString() + "|nr=" + frame.numR.ToString(); frame.pidInfo = new PidInfo(); ptr = frame.pidInfo.Decode(buf, ptr, out r); if (frame.pidInfo.cmdDecode.Equals(PidInfo.CommandDecode.Standard)) { // // On standard PID fields, pre-load the segmentation chuck data where the PID used to be in the buffer. // Extended info will already have the correct segmentation chunk info there. // buf[ptr] = Segmenter.StartOfSegment; } frame.iBuf = Support.PackByte(buf, ptr, (buf.Length - ptr)); s = s + r + "|len:" + frame.iBuf.Length.ToString() + "|txt:(" + Support.GetString(frame.iBuf) + ")"; return(ptr); }
public Byte[] RecvDatagram() { // // Handle returned datagram packets. Segmented packets are reassembled before returning // Byte[] tmpB = null; Int32 ptr = 0; Int32 j = 0; Byte[] segBuf = null; Int32 chunksRemaining = 0; // // Start the timeout timer. // timerSegmenter.Start(); do { // // If this is our first time through, look at the number of packets remaining // to determine how much buffer space we'll need and allocate it. // segBuf = (Byte[])recvDatagramQ.Dequeue(); if (segBuf == null) { timerSegmenter.Stop(); return(null); } chunksRemaining = segBuf[0] & 0x7f; if ((segBuf[0] & Segmenter.StartOfSegment) == Segmenter.StartOfSegment) { // // If the start of segment bit is set, look at the number of chunks remaining // to determine how much buffer space we'll need and allocate it. // tmpB = new Byte[MAXUIFRAME * (chunksRemaining + 1)]; } if (tmpB == null) { // // No start of segment flag specified. Return null // timerSegmenter.Stop(); return(null); } // // Add this packet to the total // j = 1; while (j < segBuf.Length) { tmpB[ptr++] = segBuf[j++]; } } while (chunksRemaining > 0); // // Stop the timer. // timerSegmenter.Stop(); return(Support.PackByte(tmpB, 0, ptr)); }
// // 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 static TransmitFrame Encode(Station stl, Connection.ConnectionParameterBuf cBuf, Station.CommandResponse cmdResp, Int32 pfBit) { // // Build the XID frame to send // TransmitFrame commandFrame = new TransmitFrame(); Byte[] stlB = stl.GetStationAddresBuffer(cmdResp); Int32 ptr = stlB.Length; Int32 t; Int32 c; Int32 paramPtr = 0; Byte[] tmpP = new Byte[30]; commandFrame.ibuf = new Byte[tmpP.Length + stlB.Length]; // overallocate buffer space to handle worst case. We'll trim later commandFrame.frameType = FrameTypes.XIDType; commandFrame.seqNumMode = SequenceNumberMode.Mod8; commandFrame.cmdOctetPtr = stlB.Length; stlB.CopyTo(commandFrame.ibuf, 0); // Load station address fields commandFrame.ibuf[ptr++] = (Byte)(((Int32)FrameTypes.XIDType) | (pfBit << 4)); commandFrame.ibuf[ptr++] = (Byte)(FormatIdentifier.GeneralPurposeXIDInfo); commandFrame.ibuf[ptr++] = (Byte)(GroupIdentifier.ParameterNegotiation); // // Load parameters to negotiate // t = (Int32)ClassOfProcedures.BalancedABMHalfDup; tmpP[paramPtr++] = (Byte)(ParameterIndicator.ClassOfProcedures); tmpP[paramPtr++] = (Byte)2; tmpP[paramPtr++] = (Byte)((t >> 8) & 0xff); tmpP[paramPtr++] = (Byte)(t & 0x7f); tmpP[paramPtr++] = (Byte)(ParameterIndicator.HDLCOptionalParams); tmpP[paramPtr++] = (Byte)3; tmpP[paramPtr++] = (Byte)(cBuf.optionalFuncByte0); tmpP[paramPtr++] = (Byte)(cBuf.optionalFuncByte1); tmpP[paramPtr++] = (Byte)(cBuf.optionalFuncByte2); // // The IFrame size specified here is in bits. Check to see how many bytes we'll need to specify // tmpP[paramPtr++] = (Byte)(ParameterIndicator.RXIFieldLen); c = cBuf.maxIFrame * 8; if (c >= 65536) { // // Need 4 bytes to specify the window size // tmpP[paramPtr++] = (Byte)4; tmpP[paramPtr++] = (Byte)((c >> 24) & 0xff); tmpP[paramPtr++] = (Byte)((c >> 16) & 0xff); } else { // // Need only 2 bytes // tmpP[paramPtr++] = (Byte)2; } tmpP[paramPtr++] = (Byte)((c >> 8) & 0xff); tmpP[paramPtr++] = (Byte)(c & 0xff); tmpP[paramPtr++] = (Byte)(ParameterIndicator.RXWindowSize); tmpP[paramPtr++] = (Byte)1; tmpP[paramPtr++] = (Byte)(cBuf.maxWindowSize & 0xff); // // The Ack timer is specified in mSec. Check to see how many bytes we'll need // tmpP[paramPtr++] = (Byte)(ParameterIndicator.AckTimer); if (cBuf.ackTimer >= 65536) { // // Need 4 bytes to specify ack timer // tmpP[paramPtr++] = (Byte)4; tmpP[paramPtr++] = (Byte)((cBuf.ackTimer >> 24) & 0xff); tmpP[paramPtr++] = (Byte)((cBuf.ackTimer >> 16) & 0xff); } else { // // Need only 2 bytes // tmpP[paramPtr++] = (Byte)2; } tmpP[paramPtr++] = (Byte)((cBuf.ackTimer >> 8) & 0xff); tmpP[paramPtr++] = (Byte)(cBuf.ackTimer & 0xff); tmpP[paramPtr++] = (Byte)(ParameterIndicator.NumRetries); tmpP[paramPtr++] = (Byte)1; tmpP[paramPtr++] = (Byte)(cBuf.maxRetry & 0xff); tmpP = Support.PackByte(tmpP, 0, paramPtr); // Pack it down // // Add parameter length field to buffer // commandFrame.ibuf[ptr++] = (Byte)((tmpP.Length >> 8) & 0xff); commandFrame.ibuf[ptr++] = (Byte)(tmpP.Length & 0xff); // // Add the parameters to the buffer // tmpP.CopyTo(commandFrame.ibuf, ptr); ptr += tmpP.Length; commandFrame.ibuf = Support.PackByte(commandFrame.ibuf, 0, ptr); //Pack it down return(commandFrame); }