public async Task SendCommandAsync(CommandArgs args)
		{
			if(outputStream != null)
			{
				var bytes = GeneratePackage(args);
				await outputStream.WriteAsync(bytes, 0, bytes.Length);
				await outputStream.FlushAsync();
			}
		}
		protected void FireSendCommand(byte relay, bool value)
		{
			if (SendCommand != null)
			{
				lock (SendCommand)
				{
					CommandArgs args = new CommandArgs();
					args.Type = CommandType.Set;
					args.Command = Command.Command.Relay;
					args.Value = new byte[] { (byte)((relay << 4) | ((value)?1:0)) };
					SendCommand(this, args);
				}
			}
		}
		public async void OnCommandRecived(object sender, CommandArgs args)
		{
			if (args.Type == CommandType.Set && args.Command == Command.Command.Relay)
			{
				byte[] value = args.Value;
				if (value != null && value.Length == 1)
				{
					byte b = value[0];
					int relay = (b >> 4);
					int val = b & 1;
					var dispatcher = Deployment.Current.Dispatcher;

					switch(relay)
					{
						case 1:
							relay1 = val == 1;
							dispatcher.BeginInvoke(() =>
								{
									OnPropertyChanged("Relay1");
								});
							break;
						case 2:
							relay2 = val == 1;
							dispatcher.BeginInvoke(() =>
							{
								OnPropertyChanged("Relay2");
							});
							break;
						case 3:
							relay3 = val == 1;
							dispatcher.BeginInvoke(() =>
							{
								OnPropertyChanged("Relay3");
							});
							break;
						case 4:
							relay4 = val == 1;
							dispatcher.BeginInvoke(() =>
							{
								OnPropertyChanged("Relay4");
							});
							break;
						default:
							break;
					}
				}
			}
		}
		protected async override void OnNavigatedTo(NavigationEventArgs e)
		{
			base.OnNavigatedTo(e);
			if (Connection == null)
			{
				if (NavigationService.CanGoBack)
				{
					NavigationService.GoBack();
				}
				else
				{
					NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));

				}
				return;
			}

			if (processer == null || commandvm == null || commandvm.RGBLed == null)
			{
				processer = new Processer();
				commandvm = new CommandViewModel();
				commandvm.Relay = new RelayViewModel();
				processer.CommandRecived += commandvm.Relay.OnCommandRecived;
				commandvm.RGBLed = new RGBLedViewModel();
				processer.CommandRecived += commandvm.RGBLed.OnCommandRecived;
				commandvm.Relay.SendCommand += sendCommand;
				commandvm.RGBLed.SendCommand += sendCommand;
				DataContext = commandvm;
				processer.SetInputStream(Connection.InputStream.AsStreamForRead());
				processer.SetOutputStream(Connection.OutputStream.AsStreamForWrite());

				if (NavigationContext.QueryString != null && NavigationContext.QueryString.ContainsKey("commandName"))
				{
					if (String.Compare("LightsOn", NavigationContext.QueryString["commandName"], StringComparison.CurrentCulture) == 0)
					{
						commandvm.Relay.Relay1 = commandvm.Relay.Relay2 = commandvm.Relay.Relay3 = commandvm.Relay.Relay4 = true;
					}
					else if (String.Compare("LightsOff", NavigationContext.QueryString["commandName"], StringComparison.CurrentCulture) == 0)
					{
						commandvm.Relay.Relay1 = commandvm.Relay.Relay2 = commandvm.Relay.Relay3 = commandvm.Relay.Relay4 = false;
					}
				}

				CommandArgs args = new CommandArgs();
				args.Type = CommandType.Get;
				args.Command = Command.Command.All;
				args.Value = new byte[0];
				
				colors.AddRange(new ColorViewModel[]
				{
					new ColorViewModel
					{
						Name = "None",
						Color = Colors.Black
					},
					new ColorViewModel()
					{
						Name = "Blue",
						Color = Colors.Blue
					},
					new ColorViewModel
					{
						Name = "Brown",
						Color = Colors.Brown
					},
					new ColorViewModel{
						Name = "Cyan",
						Color = Colors.Cyan
					},
					new ColorViewModel
					{
						Name = "DarkGray",
						Color = Colors.DarkGray
					},
					new ColorViewModel
					{
						Name = "Gray",
						Color = Colors.Gray
					},
					new ColorViewModel
					{
						Name = "Green",
						Color = Colors.Green
					},
					new ColorViewModel
					{
						Name = "LightGray",
						Color = Colors.LightGray
					},
					new ColorViewModel
					{
						Name = "Magenta",
						Color = Colors.Magenta
					},
					new ColorViewModel
					{
						Name = "Orange",
						Color = Colors.Orange
					},
					new ColorViewModel
					{
						Name = "Purple",
						Color = Colors.Purple
					},
					new ColorViewModel
					{
						Name = "Red",
						Color = Colors.Red
					},
					new ColorViewModel
					{
						Name = "White",
						Color = Colors.White
					},
					new ColorViewModel
					{
						Name = "Yellow",
						Color = Colors.Yellow
					}
				});
				ColorsInput.ItemsSource = colors;

				if (processer != null)
				{
					await processer.SendCommandAsync(args);
				}
			}
		}
		private async void sendCommand(object sender, CommandArgs args)
		{
			if (processer != null)
			{
				await processer.SendCommandAsync(args);
			}
		}
		protected async void FireCommandRecived(CommandArgs args)
		{
			await Task.Run(() =>
			{
				if (CommandRecived != null)
				{
					lock (CommandRecived)
					{
						CommandRecived(this, args);
					}
				}
			});
		}
		/*
		 * Package
		 * [1 byte (start) (254)][1 byte (Length in bytes max 253)][4 bytes (CommandType)][4 bytes (Command)][0-243 bytes (Data)][1 byte (CRC)][1 byte (stop) (255)]
		 */
		protected byte[] GeneratePackage(CommandArgs args)
		{
			if (args == null)
			{
				throw new ArgumentNullException("args");
			}

			byte[] bytes = null;
			if (args.Value != null)
			{
				bytes = new byte[12 + args.Value.Length];
			}
			else
			{
				bytes = new byte[12];
			}

			int tmp;

			byte crc = 255;

			bytes[0] = StartByte;
			bytes[1] = (byte)(bytes.Length - 2);
			crc = (byte)(crc ^ bytes[1]);
			tmp = (int)args.Type;
			bytes[2] = (byte)(tmp >> 24);
			crc = (byte)(crc ^ bytes[2]);
			bytes[3] = (byte)(tmp >> 16);
			crc = (byte)(crc ^ bytes[3]);
			bytes[4] = (byte)(tmp >> 8);
			crc = (byte)(crc ^ bytes[4]);
			bytes[5] = (byte)tmp;
			crc = (byte)(crc ^ bytes[5]);
			tmp = (int)args.Command;
			bytes[6] = (byte)(tmp >> 24);
			crc = (byte)(crc ^ bytes[6]);
			bytes[7] = (byte)(tmp >> 16);
			crc = (byte)(crc ^ bytes[7]);
			bytes[8] = (byte)(tmp >> 8);
			crc = (byte)(crc ^ bytes[8]);
			bytes[9] = (byte)tmp;
			crc = (byte)(crc ^ bytes[9]);

			for (int i = 0; i < args.Value.Length; i++)
			{
				bytes[i + 10] = args.Value[i];
				crc = (byte)(crc ^ args.Value[i]);
			}

			bytes[10 + args.Value.Length] = crc;
			bytes[bytes.Length - 1] = EndByte;

			return bytes;
		}
		/// <summary>
		/// We assume that you have already encountered StartByte right before you call this method.
		/// </summary>
		/// <param name="input">The Stream to read the packet from </param>
		/// <returns>null if there was an issue with the packet </returns>
		protected CommandArgs ReadPacket(Stream input)
		{
			int crc = 255;
			int length = input.ReadByte();
			if (length <= -1)
			{
				return null;
			}

			crc = crc ^ length;

			byte[] buffer = new byte[4];
			buffer[0] = (byte)input.ReadByte();
			crc = crc ^ buffer[0];
			buffer[1] = (byte)input.ReadByte();
			crc = crc ^ buffer[1];
			buffer[2] = (byte)input.ReadByte();
			crc = crc ^ buffer[2];
			buffer[3] = (byte)input.ReadByte();
			crc = crc ^ buffer[3];

			int commandType = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
			buffer[0] = (byte)input.ReadByte();
			crc = crc ^ buffer[0];
			buffer[1] = (byte)input.ReadByte();
			crc = crc ^ buffer[1];
			buffer[2] = (byte)input.ReadByte();
			crc = crc ^ buffer[2];
			buffer[3] = (byte)input.ReadByte();
			crc = crc ^ buffer[3];

			int command = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | (buffer[3]);

			buffer = new byte[length - 10];
			for (int i = 0; i < buffer.Length; i++)
			{
				buffer[i] = (byte)input.ReadByte();
				crc = crc ^ buffer[i];
			}

			byte acrc = (byte)input.ReadByte();
			if (acrc != (byte)crc)
			{
				return null;
			}

			int end = input.ReadByte();
			if (end != EndByte)
			{
				return null;
			}

			CommandArgs args = new CommandArgs();

			try
			{
				args.Type = (CommandType)commandType;
			}
			catch { return null; }

			try
			{
				args.Command = (Command)command;
			}
			catch { return null; }

			args.Value = buffer;

			return args;
		}
        public void OnCommandRecivedTest()
        {
            CommandArgs args = new CommandArgs();
            args.Type = CommandType.Set;
            args.Command = Command.Command.RGBLed;
            args.Value = new byte[] { 0, 0, 0 };

            RGBLedViewModel led = new RGBLedViewModel();
            led.SendCommand += (sender, a) => { Assert.Fail("SendCommand should not be called"); };
            int calledTimes = 0;
            bool redName = false;
            bool greenName = false;
            bool blueName = false;
            // Red
            led.PropertyChanged += (sender, a) =>
                {
                    calledTimes++;
                    if(a.PropertyName == "Red")
                    {
                        redName = true;
                    }
                    else if(a.PropertyName == "Green")
                    {
                        greenName = true;
                    }
                    else if (a.PropertyName == "Blue")
                    {
                        blueName = true;
                    }
                    else
                    {
                        Assert.Fail("{0} is not an expected PropertyName", a.PropertyName);
                    }
                };
            args.Value[0] = 123;
            args.Value[1] = 33;
            args.Value[2] = 89;

            led.OnCommandRecived(this, args);
            Assert.AreEqual(3, calledTimes, "calledTimes");
            Assert.IsTrue(redName, "redName");
            Assert.IsTrue(greenName, "greenName");
            Assert.IsTrue(blueName, "blueName");
        }
        public void OnCommandRecivedTest()
        {
            // relay1
            CommandArgs args = new CommandArgs();
            args.Type = CommandType.Set;
            args.Command = Command.Command.Relay;
            args.Value = new byte[] { 17 };
            RelayViewModel relay = new RelayViewModel();
            relay.SendCommand += (sender, a) =>
                {
                    Assert.Fail("This method should not be called");
                };
            bool called = false;
            PropertyChangedEventHandler relay1 = (sender, a) =>
                {
                    called = true;
                    Assert.AreEqual("Relay1", a.PropertyName, "PropertyName");
                };
            relay.PropertyChanged += relay1;
            relay.OnCommandRecived(this, args);
            Assert.IsTrue(called, "called");
            Assert.IsTrue(relay.Relay1, "relay.Relay1");
            relay.PropertyChanged -= relay1;

            // relay2
            called = false;
            PropertyChangedEventHandler relay2 = (sender, a) =>
                {
                    called = true;
                    Assert.AreEqual("Relay2", a.PropertyName, "PropertyName");
                };
            args.Value[0] = 33;
            relay.PropertyChanged += relay2;
            Assert.IsFalse(called, "called");
            relay.OnCommandRecived(this, args);
            Assert.IsTrue(called, "called");
            relay.PropertyChanged -= relay2;

            //relay3
            called = false;
            PropertyChangedEventHandler relay3 = (sender, a) =>
                {
                    called = true;
                    Assert.AreEqual("Relay3", a.PropertyName, "PropertyName");
                };
            args.Value[0] = 49;
            relay.PropertyChanged += relay3;
            Assert.IsFalse(called, "called");
            relay.OnCommandRecived(this, args);
            Assert.IsTrue(called, "called");
            relay.PropertyChanged -= relay3;

            //relay4
            called = false;
            PropertyChangedEventHandler relay4 = (sender, a) =>
                {
                    called = true;
                    Assert.AreEqual("Relay4", a.PropertyName, "PropertyName");
                };
            args.Value[0] = 65;
            relay.PropertyChanged += relay4;
            Assert.IsFalse(called, "called");
            relay.OnCommandRecived(this, args);
            Assert.IsTrue(called, "called");
            relay.PropertyChanged -= relay4;
        }
 public void OnCommandRecived(object sender, CommandArgs args)
 {
     if (args.Type == CommandType.Set && args.Command == Command.Command.RGBLed)
     {
         if (args.Value != null && args.Value.Length == 3)
         {
             red = args.Value[0];
             green = args.Value[1];
             blue = args.Value[2];
             var dispatcher = Deployment.Current.Dispatcher;
             dispatcher.BeginInvoke(() =>
             {
                 OnPropertyChanged("Red");
                 OnPropertyChanged("Green");
                 OnPropertyChanged("Blue");
             });
         }
     }
 }
 protected void FireSendCommand()
 {
     if (SendCommand != null)
     {
         lock (SendCommand)
         {
             CommandArgs args = new CommandArgs();
             args.Type = CommandType.Set;
             args.Command = Command.Command.RGBLed;
             args.Value = new byte[] { red, green, blue };
             SendCommand(this, args);
         }
     }
 }