Exemple #1
0
        /// <summary>
        /// Sends the command to the device specified
        /// </summary>
        /// <param name="command">The command to send</param>
        /// <param name="bulbMacAddress">The MAC address of the bulb that will receive the command (used for mesh networking)</param>
        /// <param name="panControllerMacAddress">The pan controller MAC address that will receive the command (used for mesh networking)</param>
        /// <param name="remoteIPAddress">The IP address that will physically receive the command first</param>
        /// <returns>Returns false if the command couldn't be sent for whatever reason</returns>
        private async Task <bool> SendCommandRaw(LifxCommand command, string bulbMacAddress, string panControllerMacAddress, string remoteIPAddress)
        {
            try
            {
                LifxDataPacket packet = new LifxDataPacket(command);
                packet.TargetMac        = LifxHelper.StringToByteArray(bulbMacAddress);
                packet.PanControllerMac = LifxHelper.StringToByteArray(panControllerMacAddress);

                using (var stream = await new DatagramSocket().GetOutputStreamAsync(new HostName(remoteIPAddress), LifxHelper.LIFX_PORT.ToString()))
                {
                    using (var writer = new DataWriter(stream))
                    {
                        writer.WriteBytes(packet.PacketData);
                        await writer.StoreAsync();
                    }
                }

                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }
Exemple #2
0
        /// <summary>
        /// The listner clients message recieved event handler.
        /// This is where the message will be converted into a LifxMessage and will invoke the MessageRecieved event handler if anything is subscribed to it
        /// </summary>
        /// <param name="sender">The socket that recieved the packet</param>
        /// <param name="args">Where the packet information is contained</param>
        private void lifxCommunicatorClient_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
        {
            if (IsDisposed)
            {
                return;
            }

            uint bufferArraySize = args.GetDataReader().UnconsumedBufferLength;

            Byte[] receiveBytes = new Byte[bufferArraySize];
            args.GetDataReader().ReadBytes(receiveBytes);

            LifxDataPacket packet          = new LifxDataPacket(receiveBytes);
            LifxMessage    receivedMessage = LifxHelper.PacketToMessage(packet);

            if (receivedMessage != null) // Check to make sure the packet we recieved was sent from a LIFX bulb, others can be sending on the same port
            {
                // If the packet type is a pan gateway we need to handle this a bit differently
                if (receivedMessage.PacketType == MessagePacketType.PanGateway)
                {
                    // This locks the variable and lets any senders will waiting for a pan gateway know that we have received the message and you can stop retrying
                    lock (commandsAwaitingResponse)
                    {
                        // Ensure that there are senders awaiting a message
                        if (commandsAwaitingResponse.ContainsKey(receivedMessage.PacketType))
                        {
                            commandsAwaitingResponse[receivedMessage.PacketType] = receivedMessage; // Sets the reply (from bulb) message to this message
                            messageResumer[receivedMessage.PacketType].Release();                   // Stops the senders from retrying to ask for pan gateway messages
                        }
                    }

                    // Sets up the pan handler class and assigns the bulb to it
                    LifxPanController foundPanHandler = new LifxPanController()
                    {
                        MACAddress = LifxHelper.ByteArrayToString(receivedMessage.ReceivedData.PanControllerMac),
                        IPAddress  = args.RemoteAddress.DisplayName
                    };
                    foundPanHandler.Bulbs.Add(new LifxBulb(foundPanHandler, args.RemoteAddress.DisplayName, LifxHelper.ByteArrayToString(receivedMessage.ReceivedData.PanControllerMac)));

                    // Invoke the PanControllerFound event handler
                    PanControllerFound.Invoke(this, foundPanHandler);
                    return;
                }

                // If the incoming packet isn't a pan controller, just lock the variable
                // and lets any senders that may be waiting for a return message know that we have received the message and you can stop retrying
                lock (commandsAwaitingResponse)
                {
                    // If there is someone waiting for a recieved message, i.e. the command is *meant* to receive something from the bulb
                    // let it know we have found it (Release) and assign the message to the varaible
                    // Otherwise we have received a LifxMessage we didn't ask for. Ensure that there is someone subscribed to the event handler and Invoke with the message
                    if (commandsAwaitingResponse.ContainsKey(receivedMessage.PacketType))
                    {
                        commandsAwaitingResponse[receivedMessage.PacketType] = receivedMessage;
                        messageResumer[receivedMessage.PacketType].Release();
                    }
                    else
                    {
                        if (MessageRecieved != null)
                        {
                            MessageRecieved.Invoke(this, receivedMessage);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Converts a raw <see cref="LifxDataPacket">LifxDataPacket</see> to a <see cref="LifxMessage">LifxMessage</see>
        /// </summary>
        /// <param name="packet">Raw DataPacket to convert from</param>
        /// <returns>A <see cref="LifxMessage">LifxMessage</see> if implemented or recognised otherwise null</returns>
        public static LifxMessage PacketToMessage(LifxDataPacket packet)
        {
            switch (MessagePacketTypeToEnum(packet.PacketType))
            {
            case MessagePacketType.Unknown:
                break;

            case MessagePacketType.PanGateway:
                return(new LifxPanGatewayStateMessage(packet));

            case MessagePacketType.PowerState:
                return(new LifxPowerStateMessage(packet));

            case MessagePacketType.WifiInfo:
                return(new LifxWiFiInfoMessage(packet));

            case MessagePacketType.WifiFirmwareState:
                return(new LifxWiFiFirmwareMessage(packet));

            case MessagePacketType.WifiState:
                break;

            case MessagePacketType.AccessPoint:
                break;

            case MessagePacketType.Label:
                return(new LifxLabelMessage(packet));

            case MessagePacketType.Tags:
                return(new LifxTagsMessage(packet));

            case MessagePacketType.TagLabels:
                return(new LifxTagLabelMessage(packet));

            case MessagePacketType.LightStatus:
                return(new LifxLightStatusMessage(packet));

            case MessagePacketType.TimeState:
                break;

            case MessagePacketType.ResetSwitchState:
                break;

            case MessagePacketType.DummyLoad:
                break;

            case MessagePacketType.MeshInfo:
                break;

            case MessagePacketType.MeshFirmwareState:
                break;

            case MessagePacketType.VersionState:
                break;

            case MessagePacketType.Info:
                break;

            case MessagePacketType.MCURailVoltage:
                break;

            default:
                return(null);
            }

            return(null);
        }