LIFX Developer Zone

[UDP] Send EchoRequest to Lifx


#1

Hi,

I tried many times to send UDP packet to my lifx bulb. I can turn on/off the buld but I don’t have any response from it.

I would like to try something new: sending a EchoRequest (58). But I have the same problem, the bulb does not give me any response.

Here is the packet :
\x2C\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x10\x00\x00\x00\x00\x00\x00\x00\x00\x3A\x00\x00\x00\x01\x23\x45\x67\x89\xAB\xCD\xEF

I tried to send it with a bash command (netcat):
echo "\x2C\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x10\x00\x00\x00\x00\x00\x00\x00\x00\x3A\x00\x00\x00\x01\x23\x45\x67\x89\xAB\xCD\xEF" | nc -u 192.168.1.22 56700
Note: this command works when I want to send UDP packet to turn on/off the light.

I also tried to send the UDP packet with a golang UDP client:

// Send sends a UDP packet to a dest.
// It returns an error.
func Send(dest string, packet []byte) error {
	log := logrus.WithField("from", "clientUDP")
        // Initializes the UDP cient
	addr, err := net.ResolveUDPAddr("udp", dest)
	if err != nil {
		return err
	}

	p := make([]byte, 2048)
	conn, err := net.DialUDP("udp", nil, addr)
	defer conn.Close()
	if err != nil {
		return err
	}

	log.Infof("Sending packet to %s", addr.String())
	// Sends the UDP packet
        fmt.Fprintf(conn, fmt.Sprintf("%s", packet))
        // Reads the response
	var n int
	n, err = conn.Read(p[0:])

	if err != nil {
		return err
	} else {
		log.WithFields(logrus.Fields{
			"response": string(p),
			"length":   n,
		}).Info("packet received")
	}

	return nil
}

But the client waits for a response and does not stop its process.

Do you have any idea to help me?

Thanks.


#2

Hi,

I sent the exact bytes you state in your message to my lights using my photons framework and I was able to get a response, so the messages itself is fine.

Are you able to share the whole go program you used with import statements and main() as well?


#3

actually, I got your go code to run.

It seems the message is actually incorrect and so the light didn’t think it had the whole message yet.

So sending something like the following as unhexlified bytes works 6400001492a3e060d073d512c21d00004c4946585632010120c35e76e13f7a153b00000031323334353637383961626364656600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Which corresponds to

size        : 100
protocol    : 1024
addressable : True
tagged      : False
reserved1   : b'\x00'
source      : 1625334674
target      : b'\x00\x00\x00\x00\x00\x00\x00\x00'
reserved2   : b'\x00\x00\x00\x00\x00\x00'
res_required: True
ack_required: False
reserved3   : b'\x00'
sequence    : 1
reserved4   : b'\x00\x00\x00\x00\x00\x00\x00\x00'
pkt_type    : 58
reserved5   : b'\x00\x00'
echoing     : b'123456789abcdef\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

Seems the way I was creating the message in photons from your bytes meant it was correcting the size of the packet which is why it was working for me there.


#4

Ok so I did two mistakes:

  • First: my message was incorrect. I have read the text incorrectly: the payload of the EchoRequest needs a 64 bytes-length payload. I read 64 bits. This is not the same thing…
  • Second: the echo request needs a source in its message, like every other messages giving a response to the client.

Perfect. You really helped me!

Thank you!


#5

No probs :slight_smile:


#6

I see you used my gist in your horus project, Horus: An API for LIFX devices in your LAN :slight_smile:

This is fine, but it makes some assumptions that may not be true in all circumstances:

  • The next bytes is related the bytes just sent (I think this is true in horus because you use the connection to send one message at a time and wait for the response, but if you tried to parallelise with the same connection then that won’t work)
  • The messages is received by the bulb the first time you send it. This is not always true, especially if there are many devices on the network, due to the nature of udp
  • it never reads a partial message. So if it only gets part of the message then it’s gonna fail to give back all the bytes, and the next time you read you’re gonna get weird data

Unfortunately I don’t really have answers to these problems without getting quite complicated.

But something you should be aware of.


#7

Yes, I know lots of things on my API have to be improved/fixed. That is why the version is 0.0.1 :slight_smile:
I am not a pro with UPD protocol but I will find more informations soon!

Thank you for your message!