Exemplo n.º 1
0
        public BCCentralManager(string serialPath)
        {
            SerialPath = serialPath ?? throw new ArgumentNullException(nameof(serialPath));

            // Hookup serial protocol
            _protocol = new SerialProtocol();
            _protocol.CommandResponseReceived += (sender, responsePdu) => _responsePdu = responsePdu;
            _protocol.EventReceived           += (sender, eventPdu) => _eventPdu = eventPdu;
            _protocol.ProtocolError           += (sender, error) => _protocolError = error;
        }
Exemplo n.º 2
0
 private bool CheckForResponse(out CommandResponsePdu responsePdu)
 {
     if (_responsePdu == null)
     {
         responsePdu = null;
         return(false);
     }
     responsePdu  = _responsePdu;
     _responsePdu = null;
     return(true);
 }
        public void Parse(byte ch)
        {
            if (_pduBufPos >= PDU_BUF_SIZE)
            {
                _pduBufPos = 0;
            }
            //-----------------
            // Parse PDU_TYPE
            //-----------------
            // check packet position
            if (_pduBufPos == 0)
            {
                // beginning of packet, check for correct framing/expected byte(s)
                // Packet must be either Command/Response (0x00) or Event (0x80)
                if ((ch & 0x7F) == 0x00)
                {
                    // store new character in RX buffer
                    _rxPduBuf[_pduBufPos++] = ch;
                }
            }
            else
            {
                _rxPduBuf[_pduBufPos++] = ch;
                if (_pduBufPos == (PDU_HDR_POS_CLS_ID + 1))
                {
                    //------------
                    // Parse CLSID
                    //------------
                    if (_rxPduBuf[PDU_HDR_POS_CLS_ID] != (byte)ClassId.BlueCats)
                    {
                        if ((_rxPduBuf[PDU_HDR_POS_CLS_ID] & 0x7F) == 0x00)
                        {
                            _rxPduBuf[0] = _rxPduBuf[PDU_HDR_POS_CLS_ID];
                            _pduBufPos   = 1;
                        }
                        else
                        {
                            _pduBufPos = 0; // bad sync, reset pdu buffer
                        }
                    }
                }
                //-----------------
                // Parse PAY_LEN
                //-----------------
                else if (_pduBufPos == (PDU_HDR_POS_PAY_LEN + 1))
                {
                    _pduPayLen = ch;
                }
                else if (_pduBufPos >= PDU_HDR_LEN)
                {
                    //-----------------------------
                    // Parse header CRC8 and verify
                    //-----------------------------
                    if (_pduBufPos == PDU_HDR_LEN)
                    {
                        // check pdu header crc8
                        byte hdrCrc8 = Crc8(_rxPduBuf, 0, PDU_HDR_LEN - 1);
                        if (hdrCrc8 != _rxPduBuf[PDU_HDR_POS_CRC8])
                        {
                            _pduBufPos = 0; // crc failed, reset pdu buffer
                            var errMsg = $"Header CRC8 does not match (calculated: 0x{hdrCrc8:2X}, given: 0x{_rxPduBuf[ PDU_HDR_POS_CRC8 ]:2X}";
                            ProtocolError?.Invoke(this, errMsg);
                        }
                    }

                    //---------------------
                    // Full packet received
                    //---------------------
                    if (_pduBufPos == (_pduPayLen + PDU_HDR_LEN))
                    {
                        // just received last expected byte, reset pdu buffer
                        _pduBufPos = 0;

                        //------------------------------
                        // Parse payload CRC8 and verify
                        //------------------------------
                        if (_pduPayLen > 0)
                        {
                            // check pdu payload crc8
                            byte payCrc8 = Crc8(_rxPduBuf, PDU_PAY_POS, _pduPayLen);
                            if (payCrc8 != _rxPduBuf[PDU_HDR_POS_PAY_CRC8])
                            {
                                var errMsg = $"Header CRC8 does not match (calculated: 0x{payCrc8:X2}, given: 0x{_rxPduBuf[ PDU_HDR_POS_CRC8 ]:X2})";
                                ProtocolError?.Invoke(this, errMsg);
                                return;
                            }
                        }

                        //-----------
                        // Handle RSP
                        //-----------
                        if (_rxPduBuf[PDU_HDR_POS_PDU_TYPE] == (byte)PduType.Command)
                        {
                            if (_pduPayLen <= 0)
                            {
                                _pduBufPos = 0; // reset pdu buffer
                                ProtocolError?.Invoke(this, "Missing response code for response");
                            }
                            var payloadBytes = _rxPduBuf.Take(_pduPayLen + PDU_HDR_LEN).ToArray();
                            var pdu          = CommandResponsePdu.FromByteArray(payloadBytes);
                            CommandResponseReceived?.Invoke(this, pdu);
                        }
                        //-----------
                        // Handle EVT
                        //-----------
                        else if (_rxPduBuf[PDU_HDR_POS_PDU_TYPE] == (byte)PduType.Event)
                        {
                            var payloadBytes = _rxPduBuf.Take(_pduPayLen + PDU_HDR_LEN).ToArray();
                            var pdu          = EventPdu.FromByteArray(payloadBytes);
                            EventReceived?.Invoke(this, pdu);
                        }
                    }
                }
            }
        }