Beispiel #1
0
        /// <summary>
        /// Callback called after a <see cref="BluetoothUnlockResponsePacket"/> is received and the
        /// corresponding Packet Received event has been fired.
        /// </summary>
        /// <param name="sender">The object that sent the event.</param>
        /// <param name="e">The Packet Received event.</param>
        /// <seealso cref="PacketReceivedEventArgs"/>
        private void ReceiveBLEPacket(object sender, PacketReceivedEventArgs e)
        {
            if (!(e.ReceivedPacket is XBeeAPIPacket) || ((XBeeAPIPacket)e.ReceivedPacket).FrameType != APIFrameType.BLE_UNLOCK_RESPONSE)
            {
                return;
            }

            BluetoothUnlockResponsePacket response = (BluetoothUnlockResponsePacket)e.ReceivedPacket;

            // Check if the packet contains the expected phase or an error.
            if (response.SrpPhase != SrpPhase.UNKNOWN && response.SrpPhase != expectedPhase)
            {
                return;
            }

            unlockResponse = response;

            // Continue execution by notifying the lock object.
            lock (unlockLock)
            {
                Monitor.Pulse(unlockLock);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Starts the bluetooth authentication with the XBee device.
        /// </summary>
        /// <exception cref="BluetoothAuthenticationException">If there is any error performing the
        /// bluetooth authentication.</exception>
        /// <exception cref="InterfaceNotOpenException">If the connection interface is not open.</exception>
        /// <exception cref="XBeeException">If there is any error in the communication process.</exception>
        public void Authenticate()
        {
            // Check connection.
            if (!device.IsOpen)
            {
                throw new InterfaceNotOpenException();
            }

            device.PacketReceived += ReceiveBLEPacket;

            try
            {
                User user = new User(API_USERNAME, password);

                // Phase 1.
                byte[] clientEphemeral = user.StartAuthentication();
                expectedPhase  = SrpPhase.PHASE_2;
                unlockResponse = null;
                device.SendPacketAsync(new BluetoothUnlockPacket(SrpPhase.PHASE_1, clientEphemeral));
                lock (unlockLock)
                {
                    Monitor.Wait(unlockLock, TIMEOUT_AUTH);
                }
                CheckResponsePacket();

                // Phase 2.
                int    index = 0;
                byte[] salt  = new byte[LENGTH_SALT];
                Array.Copy(unlockResponse.Data, index, salt, 0, salt.Length);
                index += LENGTH_SALT;
                byte[] serverEphemeral = new byte[LENGTH_EPHEMERAL];
                Array.Copy(unlockResponse.Data, index, serverEphemeral, 0, serverEphemeral.Length);

                // Phase 3.
                byte[] clientSessionProof = user.ProcessChallenge(salt, serverEphemeral);
                expectedPhase  = SrpPhase.PHASE_4;
                unlockResponse = null;
                device.SendPacketAsync(new BluetoothUnlockPacket(SrpPhase.PHASE_3, clientSessionProof));
                lock (unlockLock)
                {
                    Monitor.Wait(unlockLock, TIMEOUT_AUTH);
                }
                CheckResponsePacket();

                // Phase 4.
                index = 0;
                byte[] serverSessionProof = new byte[LENGTH_SESSION_PROOF];
                Array.Copy(unlockResponse.Data, index, serverSessionProof, 0, serverSessionProof.Length);
                index  += LENGTH_SESSION_PROOF;
                TxNonce = new byte[LENGTH_NONCE];
                Array.Copy(unlockResponse.Data, index, TxNonce, 0, TxNonce.Length);
                index  += LENGTH_NONCE;
                RxNonce = new byte[LENGTH_NONCE];
                Array.Copy(unlockResponse.Data, index, RxNonce, 0, RxNonce.Length);

                user.VerifySession(serverSessionProof);

                if (!user.authenticated)
                {
                    throw new BluetoothAuthenticationException(string.Format(ERROR_AUTH_EXTENDED, ERROR_BAD_PROOF));
                }

                // Save the sesion key.
                Key = user.SessionKey;
            }
            catch (IOException e)
            {
                throw new XBeeException(ERROR_WRITING, e);
            }
            finally
            {
                device.PacketReceived -= ReceiveBLEPacket;
            }
        }
        /// <summary>
        /// Parses the given API payload to get the right API packet, depending on its API
        /// type (<c><paramref name="payload"/>[0]</c>).
        /// </summary>
        /// <param name="payload">The payload of the API frame.</param>
        /// <returns>The corresponding API packet or <see cref="UnknownXBeePacket"/> if the frame API
        /// type is unknown.</returns>
        /// <exception cref="InvalidPacketException">If the payload is invalid for the specified
        /// frame type.</exception>
        /// <seealso cref="APIFrameType"/>
        /// <seealso cref="XBeePacket"/>
        private XBeePacket ParsePayload(byte[] payload)
        {
            // Get the API frame type.
            APIFrameType apiType = APIFrameType.UNKNOWN.Get(payload[0]);

            // Parse API payload depending on API ID.
            XBeePacket packet = null;

            switch (apiType)
            {
            case APIFrameType.TX_64:
                packet = TX64Packet.CreatePacket(payload);
                break;

            case APIFrameType.TX_16:
                packet = TX16Packet.CreatePacket(payload);
                break;

            case APIFrameType.BLE_UNLOCK:
                packet = BluetoothUnlockPacket.CreatePacket(payload);
                break;

            case APIFrameType.USER_DATA_RELAY:
                packet = UserDataRelayPacket.CreatePacket(payload);
                break;

            case APIFrameType.AT_COMMAND:
                packet = ATCommandPacket.CreatePacket(payload);
                break;

            case APIFrameType.AT_COMMAND_QUEUE:
                packet = ATCommandQueuePacket.CreatePacket(payload);
                break;

            case APIFrameType.TRANSMIT_REQUEST:
                packet = TransmitPacket.CreatePacket(payload);
                break;

            case APIFrameType.EXPLICIT_ADDRESSING_COMMAND_FRAME:
                packet = ExplicitAddressingPacket.CreatePacket(payload);
                break;

            case APIFrameType.REMOTE_AT_COMMAND_REQUEST:
                packet = RemoteATCommandPacket.CreatePacket(payload);
                break;

            case APIFrameType.TX_SMS:
                packet = TXSMSPacket.CreatePacket(payload);
                break;

            case APIFrameType.TX_IPV4:
                packet = TXIPv4Packet.CreatePacket(payload);
                break;

            case APIFrameType.TX_REQUEST_TLS_PROFILE:
                packet = TXTLSProfilePacket.CreatePacket(payload);
                break;

            case APIFrameType.RX_64:
                packet = RX64Packet.CreatePacket(payload);
                break;

            case APIFrameType.RX_16:
                packet = RX16Packet.CreatePacket(payload);
                break;

            case APIFrameType.RX_IO_64:
                packet = RX64IOPacket.CreatePacket(payload);
                break;

            case APIFrameType.RX_IO_16:
                packet = RX16IOPacket.CreatePacket(payload);
                break;

            case APIFrameType.AT_COMMAND_RESPONSE:
                packet = ATCommandResponsePacket.CreatePacket(payload);
                break;

            case APIFrameType.TX_STATUS:
                packet = TXStatusPacket.CreatePacket(payload);
                break;

            case APIFrameType.MODEM_STATUS:
                packet = ModemStatusPacket.CreatePacket(payload);
                break;

            case APIFrameType.TRANSMIT_STATUS:
                packet = TransmitStatusPacket.CreatePacket(payload);
                break;

            case APIFrameType.RECEIVE_PACKET:
                packet = ReceivePacket.CreatePacket(payload);
                break;

            case APIFrameType.EXPLICIT_RX_INDICATOR:
                packet = ExplicitRxIndicatorPacket.CreatePacket(payload);
                break;

            case APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR:
                packet = IODataSampleRxIndicatorPacket.CreatePacket(payload);
                break;

            case APIFrameType.REMOTE_AT_COMMAND_RESPONSE:
                packet = RemoteATCommandResponsePacket.CreatePacket(payload);
                break;

            case APIFrameType.RX_SMS:
                packet = RXSMSPacket.CreatePacket(payload);
                break;

            case APIFrameType.BLE_UNLOCK_RESPONSE:
                packet = BluetoothUnlockResponsePacket.CreatePacket(payload);
                break;

            case APIFrameType.USER_DATA_RELAY_OUTPUT:
                packet = UserDataRelayOutputPacket.CreatePacket(payload);
                break;

            case APIFrameType.RX_IPV4:
                packet = RXIPv4Packet.CreatePacket(payload);
                break;

            case APIFrameType.UNKNOWN:
            default:
                packet = UnknownXBeePacket.CreatePacket(payload);
                break;
            }
            return(packet);
        }