private void WriteLighMode(uint lightMode)
        {
            Task.Run(async() =>
            {
                OnewheelBoard onewheel = OnewheelConnectionHelper.INSTANCE.GetOnewheel();
                if (onewheel is null)
                {
                    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => ShowInfo("Updating light mode failed - not connected!", 5000));
                }
                else
                {
                    GattWriteResult result = await onewheel.WriteShortAsync(OnewheelCharacteristicsCache.CHARACTERISTIC_LIGHTING_MODE, (short)lightMode);

                    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        if (result != null && result.Status == GattCommunicationStatus.Success)
                        {
                            ShowInfo("💡 Light mode updated!", 5000);
                        }
                        else
                        {
                            ShowInfo("Failed to update light mode: " + (result == null ? "characteristic not found" : result.Status.ToString()), 5000);
                        }
                    });
                }
            });
        }
Пример #2
0
        //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\
        #region --Set-, Get- Methods--
        public void SetBoard(OnewheelBoard onewheel)
        {
            UnSubscribeFromEvents();
            this.onewheel = onewheel;
            SubscribeToEvents();

            ShowBattery();
            ShowBoard();
        }
Пример #3
0
        //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\
        #region --Set-, Get- Methods--
        public void SetOnewheel(OnewheelBoard onewheel)
        {
            UnsubscribeFromEvents();
            this.onewheel = onewheel;
            SubscribeToEvents();

            Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                ShowOnewheel();
                SetVisability();
            }).AsTask();
        }
Пример #4
0
        private string GetOwTypeName(OnewheelBoard onewheel)
        {
            switch (onewheel.owType)
            {
            case OnewheelType.ONEWHEEL_PLUS_XR:
                return("xr");

            case OnewheelType.ONEWHEEL_PINT:
                return("pint");

            default:
                return("");
            }
        }
Пример #5
0
        /// <summary>
        /// Calculates the response for the given challenge.
        /// Based on: https://github.com/OnewheelCommunityEdition/OWCE_App/blob/4fc1923323543db849deccbf2998646cdf1bae31/OWCE/OWCE/OWBoard.cs#L899-L914
        /// </summary>
        /// <param name="challenge">The challenge send by the Onewheel.</param>
        /// <returns>The response for the given challenge.</returns>
        private async Task <byte[]> CalcResponseAsync(byte[] challenge, OnewheelBoard onewheel)
        {
            List <byte> response = new List <byte>(20);

            response.AddRange(CHALLENGE_FIRST_BYTES);

            // Get bytes 3 through to 19 (start 3, length 16)
            byte[] apiKeyArray = new byte[16];
            Buffer.BlockCopy(challenge, 3, apiKeyArray, 0, 16);

            // Convert to hex string.
            string apiKey = Utils.ByteArrayToHexString(apiKeyArray);

            // Fetch the Token from the server:
            return(await FetchTokenAsync(apiKey, onewheel));
        }
Пример #6
0
        private async Task UpdateLightLevelAsync()
        {
            OnewheelBoard board = OnewheelConnectionHelper.INSTANCE.GetOnewheel();

            if (board is null)
            {
                return;
            }

            try
            {
                byte[] data = { WhiteValue, RedValue };
                await board.WriteBytesAsync(Uuid, data);

                Logger.Info("Updated " + Description + " to " + WhiteValue + " and " + RedValue);
            }
            catch (Exception e)
            {
                Logger.Error("Failed to update light level!", e);
            }
        }
Пример #7
0
 private async void printAll_btn_Click(object sender, RoutedEventArgs e)
 {
     OnewheelBoard onewheel = OnewheelConnectionHelper.INSTANCE.GetOnewheel();
     await onewheel?.PrintAllCharacteristicsAsync();
 }
Пример #8
0
 //--------------------------------------------------------Constructor:----------------------------------------------------------------\\
 #region --Constructors--
 /// <summary>
 /// Basic Constructor
 /// </summary>
 /// <history>
 /// 17/11/2018 Created [Fabian Sauter]
 /// </history>
 public OnewheelChangedEventArgs(OnewheelBoard onewheel)
 {
     this.ONEWHEEL = onewheel;
 }
Пример #9
0
        //--------------------------------------------------------Constructor:----------------------------------------------------------------\\
        #region --Constructors--


        #endregion
        //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\
        #region --Set-, Get- Methods--


        #endregion
        //--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\
        #region --Misc Methods (Public)--
        public abstract Task CalcAndSendResponseAsync(List <byte> serialReadCache, OnewheelBoard onewheel);
Пример #10
0
 //--------------------------------------------------------Constructor:----------------------------------------------------------------\\
 #region --Constructors--
 public OnewheelUnlockHelper(OnewheelBoard onewheel)
 {
     this.ONEWHEEL = onewheel;
     OnewheelConnectionHelper.INSTANCE.CACHE.CharacteristicChanged += CACHE_CharacteristicChanged;
 }
Пример #11
0
        //--------------------------------------------------------Constructor:----------------------------------------------------------------\\
        #region --Constructors--


        #endregion
        //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\
        #region --Set-, Get- Methods--


        #endregion
        //--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\
        #region --Misc Methods (Public)--
        public override async Task CalcAndSendResponseAsync(List <byte> serialReadCache, OnewheelBoard onewheel)
        {
            byte[] challenge = serialReadCache.ToArray();
            byte[] response  = CalcResponse(challenge);

            await onewheel.WriteBytesAsync(OnewheelCharacteristicsCache.CHARACTERISTIC_UART_SERIAL_WRITE, response);

            Logger.Info("Sent Gemini unlock response to Onewheel challenge.");
        }
Пример #12
0
        /// <summary>
        /// Based on: https://github.com/OnewheelCommunityEdition/OWCE_App/blob/4fc1923323543db849deccbf2998646cdf1bae31/OWCE/OWCE/OWBoard.cs#L981
        /// </summary>
        /// <param name="apiKey"></param>
        /// <param name="onewheel"></param>
        /// <returns></returns>
        private async Task <byte[]> FetchTokenAsync(string apiKey, OnewheelBoard onewheel)
        {
            string owType     = GetOwTypeName(onewheel);
            string deviceName = GetDeviceName(onewheel);
            OnewheelApiCredentials apiCredentials = new OnewheelApiCredentials(deviceName);

            // Check if we have already an API token cached for this device:
            if (Vault.LoadCredentials(apiCredentials) && string.Equals(apiKey, apiCredentials.apiKey))
            {
                return(Utils.HexStringToByteArray(apiCredentials.apiToken));
            }

            // Else continue with requesting a new API token:
            apiCredentials.apiKey = apiKey;
            using (HttpClientHandler handler = new HttpClientHandler())
            {
                handler.AutomaticDecompression = DecompressionMethods.GZip;
                using (HttpClient client = new HttpClient())
                {
                    // Match headers as best as possible:
                    client.DefaultRequestHeaders.Clear();
                    client.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "application/json");
                    client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
                    client.DefaultRequestHeaders.TryAddWithoutValidation("Connection", "keep-alive");
                    client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Language", "en-us");
                    client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Basic Og==");
                    client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip");

                    // Use the IOS user agent:
                    client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Onewheel/0 CFNetwork/1121.2.2 Darwin/19.2.0");
                    client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
                    client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");

                    // Request unlock key based on board name, board type, and token:
                    Uri uri = BuildUri(deviceName, owType, apiKey);
                    try
                    {
                        HttpResponseMessage response = await client.GetAsync(uri);

                        if (response.IsSuccessStatusCode)
                        {
                            string responseBody = await response.Content.ReadAsStringAsync();

                            PintGeminiUnlockResponse result = JsonConvert.DeserializeObject <PintGeminiUnlockResponse>(responseBody);
                            if (result is null || string.IsNullOrEmpty(result.key))
                            {
                                throw new Exception($"Unexpected response code ({response.StatusCode})");
                            }
                            apiCredentials.apiKey = result.key;
                            Vault.StoreCredentials(apiCredentials);
                            return(Utils.HexStringToByteArray(apiCredentials.apiToken));
                        }
                        else
                        {
                            throw new Exception($"Unexpected response code ({response.StatusCode})");
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Error("Failed to perform Pint Gemini unlock.", e);
                        return(null);
                    }
                }
            }
        }
Пример #13
0
 private string GetDeviceName(OnewheelBoard onewheel)
 {
     // TODO use concrete name:
     return("".ToLowerInvariant().Replace("ow", ""));
 }