예제 #1
0
        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());
        }
예제 #2
0
        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);
        }
예제 #3
0
 public byte SendATCmdLocal(XBeeATCommand command)
 {
     byte[] tempCmdId = NextCommandId();
     SendATCmdLocalInternal(command, true, tempCmdId);
     return(tempCmdId[0]);
 }
예제 #4
0
 public void SendATCmdLocalNoResponse(XBeeATCommand command)
 {
     byte[] tempCmdId = NextCommandId();
     SendATCmdLocalInternal(command, false, tempCmdId);
 }