Пример #1
0
        public async Task <BluetoothPairResult> PairDevice(string strConnectionName)
        {
            BlutoothPairStatus status = BlutoothPairStatus.Failed;
            bool blnAbort             = false;

            using (var lockHandle = await Locker.Lock())
            {
                if (lockHandle.Successfull)
                {
                    if (m_blnPairingInProgress)
                    {
                        blnAbort = true;
                    }
                    else
                    {
                        m_blnPairingInProgress = true;
                    }
                }
                else
                {
                    blnAbort = true;
                }
            }

            try
            {
                if (m_pairingGDIO.IsValid &&
                    !blnAbort &&
                    m_UGDIO.IsValid)
                {
                    SendBaseCommand cmd     = new SendRequestDataCommand(NukiCommandType.PublicKey);
                    Sodium.KeyPair  keyPair = Sodium.PublicKeyBox.GenerateKeyPair();
                    m_connectionInfo.ClientPublicKey = new ClientPublicKey(keyPair.Public);
                    m_connectionInfo.ConnectionName  = strConnectionName;
                    if (await m_pairingGDIO.Send(cmd))                    //3.
                    {
                        var response = await m_pairingGDIO.Recieve(2000); //4.

                        if (response != null)
                        {
                            switch (response.CommandType)
                            {
                            case NukiCommandType.PublicKey:
                                //Continue
                                cmd = new SendPublicKeyComand(new ClientPublicKey(keyPair.Public));

                                if (await m_pairingGDIO.Send(cmd))     //6.
                                {
                                    m_connectionInfo.SmartLockPublicKey = ((RecievePublicKeyCommand)response).PublicKey;

                                    byte[] byDH1 = Sodium.ScalarMult.Mult(keyPair.Secret, SmartLockPublicKey);
                                    var    _0    = new byte[16];
                                    var    sigma = System.Text.Encoding.UTF8.GetBytes("expand 32-byte k");
                                    m_connectionInfo.SharedKey = new SharedKey(Sodium.KDF.HSalsa20(_0, byDH1, sigma));     //8

                                    response = await m_pairingGDIO.Recieve(2000);

                                    if (response?.CommandType == NukiCommandType.Challenge)
                                    {
                                        cmd = new SendAuthorizationAuthenticatorCommand(this);

                                        if (await m_pairingGDIO.Send(cmd))     //13
                                        {
                                            response = await m_pairingGDIO.Recieve(2000);

                                            if (response?.CommandType == NukiCommandType.Challenge)     //15
                                            {
                                                this.SmartLockNonce = ((RecieveChallengeCommand)response).Nonce;

                                                cmd = new SendAuthorizationDataCommand(strConnectionName, this);

                                                if (await m_pairingGDIO.Send(cmd))     //16
                                                {
                                                    response = await m_pairingGDIO.Recieve(2000);

                                                    if (response?.CommandType == NukiCommandType.AuthorizationID)     //19
                                                    {
                                                        m_connectionInfo.UniqueClientID = ((RecieveAuthorizationIDCommand)response).UniqueClientID;
                                                        m_connectionInfo.SmartLockUUID  = ((RecieveAuthorizationIDCommand)response).SmartLockUUID;
                                                        this.SmartLockNonce             = ((RecieveAuthorizationIDCommand)response).SmartLockNonce;
                                                        cmd = new SendAuthorization­IDConfirmationCommand(UniqueClientID, this);

                                                        if (await m_pairingGDIO.Send(cmd))     //21
                                                        {
                                                            response = await m_pairingGDIO.Recieve(3000);

                                                            if (response?.CommandType == NukiCommandType.Status)     //19
                                                            {
                                                                if (((RecieveStatusCommand)response).StatusCode == NukiErrorCode.COMPLETE)
                                                                {
                                                                    status = BlutoothPairStatus.Successfull;
                                                                }
                                                                else
                                                                {
                                                                }
                                                            }
                                                            else
                                                            {
                                                            }
                                                        }
                                                        else
                                                        {
                                                            //SendAuthorization­IDConfirmationCommand faild
                                                        }
                                                    }
                                                    else
                                                    {
                                                    }
                                                }
                                                else
                                                {
                                                }
                                            }
                                            else
                                            {
                                            }
                                        }
                                        else
                                        {
                                        }
                                    }
                                    else
                                    {
                                        //failed
                                    }
                                }
                                else
                                {
                                }
                                break;

                            case NukiCommandType.ErrorReport:
                                switch (((RecieveErrorReportCommand)response).ErrorCode)
                                {
                                case NukiErrorCode.P_ERROR_NOT_PAIRING:
                                    status = BlutoothPairStatus.PairingNotActive;
                                    break;

                                default:
                                    status = BlutoothPairStatus.Failed;
                                    break;
                                }
                                break;

                            default:
                                status = BlutoothPairStatus.Failed;
                                break;
                            }
                        }
                        else
                        {
                            status = BlutoothPairStatus.Timeout;
                        }
                    }
                    else
                    {
                        status = BlutoothPairStatus.Failed;
                    }
                }
                else
                {
                    if (m_UGDIO.IsValid || m_pairingGDIO.IsValid
                        //|| m_GDIO.IsValid
                        )
                    {
                        status = BlutoothPairStatus.MissingCharateristic;
                    }
                }
            }

            catch (Exception ex)
            {
                Log.Error("Error in pairing: {0}", ex);
                status = BlutoothPairStatus.Failed;
            }
            finally
            {
                using (var lockHandle = await Locker.Lock())
                {
                    if (status != BlutoothPairStatus.PairingInProgress)
                    {
                        m_blnPairingInProgress = false;
                    }
                }
            }

            return(new BluetoothPairResult(status, (status == BlutoothPairStatus.Successfull) ? m_connectionInfo : null));
        }
Пример #2
0
 public BluetoothPairResult(BlutoothPairStatus status, NukiConnectionConfig connectionInfo)
 {
     Status         = status;
     ConnectionInfo = connectionInfo;
 }