Beispiel #1
0
        /// <summary>
        ///     Sends a message to the Parrot RF Service.
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task <XElement> SendMessageAsync(ParrotMessage message)
        {
            if (!BluetoothClient.Connected)
            {
                throw new Exception($"{nameof(ParrotClient)} is not connected.");
            }

            _waitingList.WaitOne();

            try
            {
                // Debug message
                Console.WriteLine($"=> Sending message '{message.Request}'");

                // Send message to Parrot
                var messageBytes = message.GetRequest();

                await BluetoothClient.GetStream().WriteAsync(messageBytes, 0, messageBytes.Length);

                await BluetoothClient.GetStream().FlushAsync();

                // Hold response element
                XElement answerElement;

                // Hold notifications
                var notifyElements = new List <XElement>();

                // Receive response(s)
                do
                {
                    answerElement = XElement.Parse(await ReceiveResponseAsync());

                    // Find notificiations
                    if (answerElement.Name == "notify")
                    {
                        notifyElements.Add(answerElement);
                    }
                    else if (answerElement.Name == "answer")
                    {
                        var notifyElement = answerElement.XPathSelectElement("/notify");
                        if (notifyElement != null)
                        {
                            notifyElements.Add(notifyElement);
                        }
                    }
                } while (answerElement.Name != "answer");

                // Handle notifications
                foreach (var notifyElement in notifyElements)
                {
                    var notifyPath = notifyElement?.Attribute("path")?.Value;
                    if (notifyPath == null)
                    {
                        continue;
                    }

                    var resource = ResourceManager.Resources.FirstOrDefault(x => x.Value.Equals(notifyPath)).Key;
                    if (resource == ResourceType.UnknownResource && ZikApi.KnowMessages.Contains(notifyPath))
                    {
                        Console.WriteLine($"=> Received unhandled notification {resource} ({notifyPath})");
                        continue;
                    }
                    else if (resource == ResourceType.UnknownResource)
                    {
                        throw new UnknownNotificationException($"Received an unknown notification: {notifyPath}");
                    }

                    // Debug message
                    Console.WriteLine($"=> Dispatching notification {resource} ({notifyPath})");

                    NotificationEvent?.AsyncSafeInvoke(this, new NotifyEventArgs(resource, notifyPath));
                }

                // Return
                return(answerElement);
            }
            finally
            {
                _waitingList.Release();
            }
        }