public void Digipeat(Frame.Packet packet, Int32 relayNum) { // // Function to implement digipeating of packets // if (digipeatEnable) { // // Digipeating is enabled // if (AccessCheckOK(packet.receivedFrame.staLink.destinationStation.stationIDString) && AccessCheckOK(packet.receivedFrame.staLink.sourceStation.stationIDString) && AccessCheckOK(packet.receivedFrame.staLink.relayStation1.stationIDString) && AccessCheckOK(packet.receivedFrame.staLink.relayStation2.stationIDString)) { Byte[] tmpBuf = packet.receivedFrame.rawBuf; // // All stations listed in the packet are allowed to digipeat, so continue // // // Set the CH bit on the specified relay // tmpBuf[13 + (7 * relayNum)] |= 0x80; _localTncChannel.Send(tmpBuf); } } }
public void Send(Object packet) { // // Send data to the DLP's processing Queue // Frame.Packet tmpPkt = (Frame.Packet)packet; if (tmpPkt.receivedFrame != null) { // // Receive packet, so check to see if we should accept it. // if (AccessCheckOK(tmpPkt.receivedFrame.staLink.destinationStation.stationIDString) && AccessCheckOK(tmpPkt.receivedFrame.staLink.sourceStation.stationIDString) && AccessCheckOK(tmpPkt.receivedFrame.staLink.relayStation1.stationIDString) && AccessCheckOK(tmpPkt.receivedFrame.staLink.relayStation2.stationIDString)) { dataLinkProviderQ.Enqueue(packet); return; } } // // Transmit packet, so just send it // dataLinkProviderQ.Enqueue(packet); }
public void SendDatagram(String destinationStation, String relayStation1, String relayStation2, Byte[] buf, Frame.ProtocolVersion version) { // // Split the datagram into segment as needed and send them off // Note the buffer returned from GetNextSegment has the appropriate PID byte(s) // prepended to the data. // Int32 tmpFSize = defMaxUFrameSize; Station stationLink = new Station(); stationLink.sourceStation = _localStationAddress; stationLink.destinationStation.SetCallSign(destinationStation); if (relayStation1.Length > 0) { stationLink.relayStation1.SetCallSign(relayStation1); if (relayStation2.Length > 0) { stationLink.relayStation2.SetCallSign(relayStation2); } } // // Use user selected value for new protocol version // if (version.Equals(Frame.ProtocolVersion.V22)) { tmpFSize = _maxUFrameSize; } Segmenter segment = new Segmenter(tmpFSize, buf, Frame.FrameTypes.UIType, version); do { Frame.Packet packet = new Frame.Packet( Frame.TransmitFrameBuild(stationLink, Station.CommandResponse.DoCommand, 0, Frame.FrameTypes.UIType, segment.GetNextSegment())); dataLinkProviderQ.Enqueue(packet); } while (segment.segmentsRemaining > 0); }
Byte[] LinkTestCommon(String destinationStation, String relayStation1, String relayStation2, Byte[] buf, Int32 timeout) { Station stationLink = new Station(); stationLink.sourceStation = _localStationAddress; stationLink.destinationStation.SetCallSign(destinationStation); if (relayStation1.Length > 0) { stationLink.relayStation1.SetCallSign(relayStation1); if (relayStation2.Length > 0) { stationLink.relayStation2.SetCallSign(relayStation2); } } Frame.Packet packet = new Frame.Packet( Frame.TransmitFrameBuild(stationLink, Station.CommandResponse.DoCommand, 1, Frame.FrameTypes.TESTType, buf)); if (timeout > 0) { // // Start the timeout timer // timerTestCommandTimeout.SetTime(timeout); timerTestCommandTimeout.Start(); } dataLinkProviderQ.Enqueue(packet); // // Wait until a return packet arrives, or return null if we time out // return((Byte[])linkTestQ.Dequeue()); }
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..."); }
void DigipeatCheckAndProcess(Frame.Packet packet) { DataLinkProvider dlp = null; Int32 relayNum = 0; Int32 relayCount = 0; if (packet.receivedFrame != null) { if (packet.receivedFrame.decodeOK) { // // Packet looks OK // Station sta = packet.receivedFrame.staLink; if (sta.relayStation1.stationIDString.Length > 0) { relayCount++; } if (sta.relayStation2.stationIDString.Length > 0) { relayCount++; } if ((relayCount >= 1) && (sta.relayStation1.chBit == 0)) { // // Relay address 1 has not been repeated, so see if we have a DLP for it. // dlp = GetProvider(sta.relayStation1.stationIDString); relayNum = 1; } else if ((relayCount >= 2) && (sta.relayStation2.chBit == 0)) { // // Relay address 2 has not been repeated, so see if we have a DLP for it. // dlp = GetProvider(sta.relayStation2.stationIDString); relayNum = 2; } else { dlp = GetProvider(sta.destinationStation.stationIDString); } } if (dlp != null) { // // We have a provider, check whether this is a digi or if packet is at its final destination // if (relayNum == 0) { // // All digipeating complete (if any) so send it up for processing // dlp.Send(packet); } else { // // Need to digipeat it, so send it up for digipeating // dlp.Digipeat(packet, relayNum); } } } }
// // 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."); }