Example #1
0
        /// <summary>
        /// Sends a message to the Pebble and awaits the response.
        /// </summary>
        /// <typeparam name="T">The type of message</typeparam>
        /// <param name="message">The message content.</param>
        /// <param name="millisecondsTimeout">The milliseconds timeout.</param>
        /// <returns>A message response</returns>
        /// <exception cref="System.InvalidOperationException">A message is being waited for already</exception>
        /// <remarks>Beware when debugging that setting a breakpoint in Protocol.Run or ProtocolMessageReceived will cause the ResetEvent to time out</remarks>
        private Task <T> SendMessageAndAwaitResponseAsync <T>(P3bbleMessage message, int millisecondsTimeout = 10000)
            where T : P3bbleMessage
        {
            if (this._pendingMessageSignal != null || this.IsBusy)
            {
                throw new InvalidOperationException("A message is being waited for already");
            }

            return(Task.Run <T>(async() =>
            {
                this.IsBusy = true;

                int startTicks = Environment.TickCount;
                this._pendingMessageSignal = new ManualResetEventSlim(false);
                this._pendingMessage = message;

                // Send the message...
                await this._protocol.WriteMessage(message);

                // Wait for the response...
                this._pendingMessageSignal.Wait(millisecondsTimeout);

                T pendingMessage = null;

                if (this._pendingMessageSignal.IsSet)
                {
                    // Store any response will be null if timed out...
                    pendingMessage = this._pendingMessage as T;
                }

                // See if we have a protocol error
                LogsMessage logMessage = this._pendingMessage as LogsMessage;
                Type pendingMessageType = this._pendingMessage.GetType();

                // Clear the pending variables...
                this._pendingMessageSignal = null;
                this._pendingMessage = null;

                int timeTaken = Environment.TickCount - startTicks;

                this.IsBusy = false;

                if (pendingMessage != null)
                {
                    ServiceLocator.Logger.WriteLine(pendingMessage.GetType().Name + " message received back in " + timeTaken.ToString() + "ms");
                }
                else
                {
                    ServiceLocator.Logger.WriteLine(message.GetType().Name + " message timed out in " + timeTaken.ToString() + "ms - type received was " + pendingMessageType.ToString());
                }

                return pendingMessage;
            }));
        }
Example #2
0
        /// <summary>
        /// Creates an incoming message.
        /// </summary>
        /// <param name="endpoint">The endpoint.</param>
        /// <param name="payload">The payload.</param>
        /// <returns>A specific message type</returns>
        public static P3bbleMessage CreateMessage(Endpoint endpoint, List <byte> payload)
        {
            P3bbleMessage frame = null;

            switch (endpoint)
            {
            case Endpoint.Ping:
                frame = new PingMessage();
                break;

            case Endpoint.Version:
                frame = new VersionMessage();
                break;

            case Endpoint.Time:
                frame = new TimeMessage();
                break;

            case Endpoint.Logs:
                frame = new LogsMessage();
                break;

            case Endpoint.AppManager:
                frame = new AppManagerMessage();
                break;

            case Endpoint.MusicControl:
                frame = new MusicMessage();
                break;

            case Endpoint.ApplicationMessage:
                frame = new AppMessage(endpoint);
                break;

            case Endpoint.PutBytes:
                frame = new PutBytesMessage();
                break;
            }

            if (frame != null)
            {
                frame.GetContentFromMessage(payload);
            }

            return(frame);
        }
Example #3
0
        /// <summary>
        /// Handles protocol messages
        /// </summary>
        /// <param name="message">The message.</param>
        private async void ProtocolMessageReceived(P3bbleMessage message)
        {
            ServiceLocator.Logger.WriteLine("ProtocolMessageReceived: " + message.Endpoint.ToString());

            switch (message.Endpoint)
            {
            case Endpoint.PhoneVersion:
                // We need to tell the Pebble what we are...
                await this._protocol.WriteMessage(new PhoneVersionMessage(IsMusicControlEnabled));

                break;

            case Endpoint.Version:
                // Store version info we got from the Pebble...
                VersionMessage version = message as VersionMessage;
                this.FirmwareVersion         = version.Firmware;
                this.RecoveryFirmwareVersion = version.RecoveryFirmware;
                break;

            case Endpoint.Logs:
                if (message as LogsMessage != null)
                {
                    ServiceLocator.Logger.WriteLine("LOG: '" + (message as LogsMessage).Message + "'");
                }

                break;

            case Endpoint.MusicControl:
                var musicMessage = message as MusicMessage;
                if (this.MusicControlReceived != null && musicMessage != null && musicMessage.ControlAction != MusicControlAction.Unknown)
                {
                    this.MusicControlReceived(musicMessage.ControlAction);
                }

                break;

            default:
                break;
            }

            // Check if we're waiting for a message...
            if (this._pendingMessageSignal != null && this._pendingMessage != null)
            {
                if (this._pendingMessage.Endpoint == message.Endpoint)
                {
                    ServiceLocator.Logger.WriteLine("ProtocolMessageReceived: we were waiting for this type of message");

                    // PutBytes messages are state machines, so need special treatment...
                    if (message.Endpoint == Endpoint.PutBytes)
                    {
                        var putMessage = this._pendingMessage as PutBytesMessage;
                        if (putMessage.HandleStateMessage(message as PutBytesMessage))
                        {
                            this._pendingMessageSignal.Set();
                        }
                        else
                        {
                            await this._protocol.WriteMessage(putMessage);
                        }
                    }
                    else
                    {
                        this._pendingMessage = message;
                        this._pendingMessageSignal.Set();
                    }
                }
                else
                {
                    // We've received a Log message when we were expecting something else,
                    // this means the protocol comms got messed up somehow, we should abort...
                    if (message.Endpoint == Endpoint.Logs)
                    {
                        this._pendingMessage = message;
                        this._pendingMessageSignal.Set();
                    }
                }
            }
        }