private async void SendATCmdLocalInternal(XBeeATCommand command, bool responseRequired, byte[] tempCmdId) { int headerSize = 0; int commandSize = 0; int nbOfBytesToSend = 0; int offset = 0; byte[] atCommand = command.ATCommand; // allocate send buffer headerSize = COMMAND_PREFIX.Length + sizeof(UInt16); commandSize = AT_COMMAND_LOCAL_SEND.Length + m_commandId.Length + atCommand.Length; if (null != command.Payload) { commandSize += command.Payload.Length; } nbOfBytesToSend = headerSize + commandSize + CHECKSUM_LENGTH; byte[] buffer = new byte[nbOfBytesToSend]; // add headers offset = SetCommandHeader(ref buffer, offset, commandSize, ref AT_COMMAND_LOCAL_SEND, ref tempCmdId); // add payload offset = AdapterHelper.AddByteToBuffer(ref buffer, ref atCommand, offset); if (null != command.Payload) { byte[] payload = command.Payload; offset = AdapterHelper.AddByteToBuffer(ref buffer, ref payload, offset); } // add checksum buffer[offset] = CheckSum(ref buffer, headerSize, commandSize); if (responseRequired) { lock (m_locker) { // add new awaited response in list m_pendingATCmdList.Add(tempCmdId[0], command); } } // send command await m_serialController.WriteAsync(buffer); Debug.WriteLineIf(Logger.IsVerbose(), "command sent", command.ToString()); }
private bool CheckResponse() { bool checkNextResponse = false; int headerSize = 0; bool signalResponseReceived = false; byte[] response = null; XBeeATCommand atCommand = null; ZigBeeCommand zigBeeCommand = null; lock (m_locker) { if (COMMAND_PREFIX[0] != m_currentResponse[0]) { // response buffer is invalid => discard m_currentResponse = null; return(checkNextResponse); } headerSize = COMMAND_PREFIX.Length + sizeof(UInt16); if (m_currentResponse.Length <= headerSize) { // not enough bytes => wait for more return(checkNextResponse); } // get size of response int payloadLength = (int)AdapterHelper.UInt16FromXbeeFrame(m_currentResponse, COMMAND_PREFIX.Length); int fullResponseLength = payloadLength + headerSize + CHECKSUM_LENGTH; if (m_currentResponse.Length < fullResponseLength) { // not enough bytes => wait for more return(checkNextResponse); } // verify checksum if (IsCheckSumOk(ref m_currentResponse, headerSize, payloadLength + CHECKSUM_LENGTH)) { // trace Rx buffer to debug output Logger.TraceRxBuffer(m_currentResponse); // get frame type byte frameType = m_currentResponse[headerSize]; // find corresponding command or corresponding notification if (frameType == AT_COMMAND_LOCAL_RECEIVE[0] || frameType == AT_COMMAND_REMOTE_RECEIVE[0]) { // get command ID byte commandId = m_currentResponse[headerSize + AT_COMMAND_LOCAL_RECEIVE.Length]; if (m_pendingATCmdList.TryGetValue(commandId, out atCommand)) { Debug.WriteLineIf(Logger.IsVerbose(), "got response", atCommand.ToString()); // command found => parse response and remove from list int responseHeaderLength = sizeof(byte) + AT_COMMAND_LOCAL_RECEIVE.Length; payloadLength -= responseHeaderLength; response = new byte[payloadLength]; Array.Copy(m_currentResponse, headerSize + responseHeaderLength, response, 0, payloadLength); atCommand.ParseResponse(response); RemovePendingATCmd(commandId); signalResponseReceived = true; } else { Debug.WriteLineIf(Logger.IsVerbose(), "unmanaged response to AT COMMAND or AT COMMAND notification"); } } else if (frameType == EXPLICIT_RX_INDICATOR[0]) { int responseHeaderLength = sizeof(byte); payloadLength -= responseHeaderLength; response = new byte[payloadLength]; Array.Copy(m_currentResponse, headerSize + responseHeaderLength, response, 0, payloadLength); byte zdoSequenceNumber = m_currentResponse[headerSize + EXPLICIT_RX_INDICATOR.Length + ZigBeeCommand.GetSequenceNumberOffestInZdoFrame()]; byte zclSequenceNumber = m_currentResponse[headerSize + EXPLICIT_RX_INDICATOR.Length + ZigBeeCommand.GetSequenceNumberOffestInZclFrame()]; if ((m_pendingZigBeeCmdList.TryGetValue(zdoSequenceNumber, out zigBeeCommand) && zigBeeCommand.IsZdoCommand) || (m_pendingZigBeeCmdList.TryGetValue(zclSequenceNumber, out zigBeeCommand) && !zigBeeCommand.IsZdoCommand)) { Debug.WriteLineIf(Logger.IsVerbose(), "got response to ZDO or ZCL command", zigBeeCommand.ToString()); zigBeeCommand.ParseResponse(response); if (zigBeeCommand.IsZdoCommand) { RemovePendingZigBeeCmd(zdoSequenceNumber); } else { RemovePendingZigBeeCmd(zclSequenceNumber); } signalResponseReceived = true; } else { // check if this is an awaited notification foreach (var notification in m_ZigBeeNotificationList) { // "try" parsing response to figure out if it // correspond to a awaited notification if (notification.Value.ParseResponse(response)) { // corresponding notification found Debug.WriteLineIf(Logger.IsVerbose(), "notification of ZDO or ZCL command", notification.Value.ToString()); break; } } Debug.WriteLineIf(Logger.IsVerbose(), "unmanaged response to ZDO or ZCL command"); } } else { Debug.WriteLineIf(Logger.IsVerbose(), "received frame OK but not handled"); } } // remove response from buffer ClearResponseBuffer(fullResponseLength); if (m_currentResponse != null && m_currentResponse.Length != 0) { checkNextResponse = true; } } if (signalResponseReceived) { if (null != atCommand) { atCommand.SignalResponseReceive(); } else if (null != zigBeeCommand) { zigBeeCommand.SignalResponseReceive(); } } return(checkNextResponse); }
public byte SendATCmdLocal(XBeeATCommand command) { byte[] tempCmdId = NextCommandId(); SendATCmdLocalInternal(command, true, tempCmdId); return(tempCmdId[0]); }
public void SendATCmdLocalNoResponse(XBeeATCommand command) { byte[] tempCmdId = NextCommandId(); SendATCmdLocalInternal(command, false, tempCmdId); }