private void HandleIncomingFrame(EzspFrame ezspFrame) { if (_stateConnected && ezspFrame != null) { try { _frameHandler.HandlePacket(ezspFrame); } catch (Exception e) { Log.Error(e, "AshFrameHandler Exception processing EZSP frame: {Exception}"); } } }
/** * The command allows the Host to specify the desired EZSP version and must be sent before any other command. The * response provides information about the firmware running on the NCP. * * @param desiredVersion the requested version we support * @return the {@link EzspVersionResponse} */ public EzspVersionResponse GetVersion(int desiredVersion) { EzspVersionRequest request = new EzspVersionRequest(); request.SetDesiredProtocolVersion(EzspFrame.GetEzspVersion()); IEzspTransaction transaction = _protocolHandler.SendEzspTransaction(new EzspSingleResponseTransaction(request, typeof(EzspVersionResponse))); EzspVersionResponse response = (EzspVersionResponse)transaction.GetResponse(); if (response == null) { Log.Debug("No response from ezspVersion command"); return(null); } Log.Debug(response.ToString()); _lastStatus = EmberStatus.UNKNOWN; return(response); }
private void ParserTaskLoop() { Log.Debug("AshFrameHandler parser task started"); int exceptionCnt = 0; while (!_parserCancellationToken.IsCancellationRequested) { try { int[] packetData = GetPacket(); if (packetData == null) { continue; } AshFrame packet = AshFrame.CreateFromInput(packetData); AshFrame responseFrame = null; if (packet == null) { Log.Debug("<-- RX ASH error: BAD PACKET {Frame}", FrameToString(packetData)); // Send a NAK responseFrame = new AshFrameNak(_ackNum); } else { Log.Debug("<-- RX ASH frame: {Frame}", packet.ToString()); // Reset the exception counter exceptionCnt = 0; // Extract the flags for DATA/ACK/NAK frames switch (packet.GetFrameType()) { case AshFrame.FrameType.DATA: _statsRxData++; // Always use the ackNum - even if this frame is discarded AckSentQueue(packet.GetAckNum()); AshFrameData dataPacket = (AshFrameData)packet; // Check for out of sequence frame number if (packet.GetFrmNum() == _ackNum) { // Frame was in sequence - prepare the response _ackNum = (_ackNum + 1) & 0x07; responseFrame = new AshFrameAck(_ackNum); // Get the EZSP frame EzspFrameResponse response = EzspFrame.CreateHandler(dataPacket.GetDataBuffer()); Log.Verbose("ASH RX EZSP: {Response}", response); if (response == null) { Log.Debug("ASH: No frame handler created for {Packet}", packet); } else { NotifyTransactionComplete(response); HandleIncomingFrame(response); } } else if (!dataPacket.GetReTx()) { // Send a NAK - this is out of sequence and not a retransmission Log.Debug("ASH: Frame out of sequence - expected {Expected}, received {Received}", _ackNum, packet.GetFrmNum()); responseFrame = new AshFrameNak(_ackNum); } else { // Send an ACK - this was out of sequence but was a retransmission responseFrame = new AshFrameAck(_ackNum); } break; case AshFrame.FrameType.ACK: _statsRxAcks++; AckSentQueue(packet.GetAckNum()); break; case AshFrame.FrameType.NAK: _statsRxNaks++; SendRetry(); break; case AshFrame.FrameType.RSTACK: // Stack has been reset! HandleReset((AshFrameRstAck)packet); break; case AshFrame.FrameType.ERROR: // Stack has entered FAILED state HandleError((AshFrameError)packet); break; default: break; } } // Due to possible I/O buffering, it is important to note that the Host could receive several // valid or invalid frames after triggering a reset of the NCP. The Host must discard all frames // and errors until a valid RSTACK frame is received. if (!_stateConnected) { continue; } // Send the next frame // Note that ASH protocol requires the host always sends an ack. // Piggybacking on data packets is not allowed if (responseFrame != null) { SendFrame(responseFrame); } SendNextFrame(); } catch (Exception e) { Log.Error(e, "AshFrameHandler Exception: ", e); if (exceptionCnt++ > 10) { Log.Error("AshFrameHandler exception count exceeded: {Exception}"); _parserCancellationToken.Cancel(); } } } Log.Debug("AshFrameHandler exited."); }