PDA

View Full Version : Improved Girder feedback protocol



brockgr
March 5th, 2003, 07:41 AM
Ok,

This has been on the end of several threads so I thought I would consolidate it here.

We have several problems with the existing feedback system and so I think we need to have a think about what we really want.

Existing feedback can:
* Set button text
* Set button images
* Batch the above (images untested)
* Jump to panels (by device, macro or home)

Possible future ideas:
* Send URI's to minbrowser
* Trigger button presses
... your idea here :P ...

Feedback related events from NR to Girder.
* NRCLIENT.ADD
* NRCLIENT.REMOVE
* NRCLIENT.RESEND

The current system uses a NRCLIENT.ADD/REMOVE to register the interest of a NetRemote (the client) with Girder (the server). From then on, every event from the server is forwarded to every registered client via a TCP session (one per client per event). This has several drawbacks:

* Slow (many TCP sessions being established)
* The server does not know the state of the client - will buffer if the client unavailable.
* Restarting the server means that the client is unaware that it has lost it's registration.

Ok so proposed protocols - my suggestion is based on the suggestions of various people. This will be enabled if a port is set in the Girder feedback plugin in NetRemote - regardless of if there is a feedback panel or not (you might want jump messages without feedback labels!)

* On start up, or wake up the clients send a NRCLIENT.REGISTER containing the IP and port of the client to the server (normal Girder style internet event).
* The server if running, will respond by connecting TCP to the IP and port provided. It will then forward the current state of the feedback cache (labels and images). The connection will not be terminated.
* For all feedback, the server will send the messages down the existing connection (keeping a cache of the messages). If the connection to the client should fail for any reason, it will drop the TCP session and wait for a new NRCLIENT.REGISTER
* If the client loses the connection from the server, it will imediatly send a NRCLIENT.REGISTER message, and await a connction. If no connection is received, it will then continue to periodically (30 seconds?) send NRCLIENT.REGISTER messages until the server connects.

Downsides:
* More complicated on the client (NR) side - Ben?
* Battery life? Does 802.11b use more power with a sustainded TCP session?


Ok, on to message formats. Should we drop the optional "payload" key word? Also what happens if we have a label with an "=" in the name? If we have a continuous session we can forget batching

How about:

Label -

label_name
text_to_set
SET


Image - (1234 is the data length - should we change the SET key word?)

label_name1
jpg,1234
base_64_data
SET


Jump messages - (* is optional)

device
panel*
GODEVICE

device
panel*
GOMACROGROUP

panel
GOHOME


Any views? Anyone still reading :wink:?

Gavin

K-Wood
March 5th, 2003, 12:32 PM
Gavin:

Since I've been one of the folks trying to get feedback working consistently, I'll chime in here. Your proposal:

Ok so proposed protocols - my suggestion is based on the suggestions of various people. This will be enabled if a port is set in the Girder feedback plugin in NetRemote - regardless of if there is a feedback panel or not (you might want jump messages without feedback labels!)

* On start up, or wake up the clients send a NRCLIENT.REGISTER containing the IP and port of the client to the server (normal Girder style internet event).
* The server if running, will respond by connecting TCP to the IP and port provided. It will then forward the current state of the feedback cache (labels and images). The connection will not be terminated.
* For all feedback, the server will send the messages down the existing connection (keeping a cache of the messages). If the connection to the client should fail for any reason, it will drop the TCP session and wait for a new NRCLIENT.REGISTER
* If the client loses the connection from the server, it will imediatly send a NRCLIENT.REGISTER message, and await a connction. If no connection is received, it will then continue to periodically (30 seconds?) send NRCLIENT.REGISTER messages until the server connects.


makes alot of sense. I think this proposal would solve most of the problems I've encountered with dropped connections and registration failures (giving me the "parse error" responses when running lua feedback scripts). I've noticed that my WiFi connection dies when the phone is in use (something I need to fix by ditching the 2.4GHz phones) -- I assume that your proposal will accomodate this problem by sending a NRCLIENT.REGISTER message if and when the connection is broken.

A couple of other things -- if we don't have more than one client, would it possible to hard code the IP address and port? Or would this be problematic if we're using DHCP? Finally, would you recommend hardcording our PPC's IP address instead of using DHCP -- would this speed up the initial connection? Taking this question one step further - should we hardcode all of our connections to avoid the problem where, after a reboot, an assigned IP address for the Girder server machine changes, requiring us to reconfiguring our NR drivers?

Gavin -- keep up the good work. Making two-way communication more robust and user-friendly will continue to set NR apart from other remote control solutions and will open the door to truly idiot-proof HT operation, even for really complex HT environments.

Best,
Ken

mrallen
March 5th, 2003, 02:15 PM
Gavin,

I agree with everything above. I do not think having a persistent TCP connection is a measurable additional draw. The big hit is just from having the 802.11 radio on.

brockgr
March 5th, 2003, 07:34 PM
Ken,

My belief is to hard code nothing - anywhere. If I had my way, NR would do multicast discovery of the HTPC. However we have some limitations.

1. Girder doesn't support any kind of discovery - so it's not worth dreaming about. 2. discovery is slow. The only thing I want more than discovery is a fast startup time on NR. For these reasons I think we have no choice bu to hard code the IP of the Girder (or Girder-like - Stewart :) ) server into NR. I also recomend not using DHCP for NR since it adds a (small) bit of time to establishing a network session.

However I don't think there should be any reason to hard code the NR (client) IP's on Girder (server) any more than any other Client - Server protocol. Hard coding on the server also limits our ability to accept arbitary, or multiple clients (some users will want DHCP regardless).

In summary: Client knows where server is. Client tells server where it is.

In an ideal world I would like to use the established NR->Girder Internet Events socket for sending feedback, but for simplicity, a second socket will probably be better.

Gavin

mrallen
March 5th, 2003, 08:57 PM
<homer>mmmmrm, multicast</homer>

seriously, this would be cool and it would not have to be slow. I'm using rendezvous (zeroconf) in another java project and it's quite fast. It's also small and simple to code.

another thing I'd like to do (please, don't shoot) would be to use bluetooth discovery and have components send their control CCF when you are within range. wander around the grounds and get controls for whatever you're near.

Ben S
March 7th, 2003, 01:35 PM
My apologies for not responding to this thread yet. I'm thinking stuff through, and I plan on posting shortly.

I think I should either opensource NetRemote soon, or we should form a team to work on this, because my other priorities seem to be slowing development on these great ideas you guys are having.

Ben S
March 10th, 2003, 04:39 PM
Howdy folks.

Gavin, I think your ideas have a lot of merit.

Just to make sure I've got it right, let me echo it back to you.

When NetRemote -starts-, it will connect to a given IP/Port within Girder. This will be the "talk" channel, while the current IP/Port will be for event delivery ("event" channel). So there are two channels open. Both will stay open after initial handshake. I don't think we can combine these without breaking standard Girder compatibility (and the ability to reuse NetRemote's IES configuration across multiple clients (MainLobby, HouseBot, CQC, etc.))

Handshake from NetRemote consists of connecting to the IP/Port. NetRemote will post a message on the "talk" channel (just connected) of "NRCLIENT.REGISTER", which is basically saying "we just connected, I'm a valid NetRemote client, register me and send me the current state".

Lua will send back the entire current state of all values.

NetRemote will now post messages to Girder via the "event" channel as normal. Lua will post messages back to NetRemote on the "talk" channel.

If, for any reason, NetRemote loses a connection, it will reconnect and rehandshake.

If, for any reason, Lua loses a connection, it will clear that connection from the connected clients.

Okay, as for messages, how about

1) A set command
SET "[label in quotes]" "[value in quotes]"

2) A jump command
JUMP [H|M|D] "[device in quotes (optional)]" "[panel in quotes (optional)]"

3) Image data
SETIMAGE "[label in quotes]" [extension] [size]
image data (in raw byte form, no Base64 encode)

As for other issues)

IP hardcoding I don't think is required. Because NetRemote initiates the connection, Girder (lua) won't care where the client initiated from, as long as the socket stays open. Also, the drivers now support host names, so the dhcp IP address should become a non-issue.

Multicast is doable, and I have some code in the Girder driver right now to listen, but it's disabled. I think Stewart's comments have a lot of merit, about discovery. I'm not familiar with Bluetooth Discovery, so I'm not sure if that's something special, but theoretically MJB and Girder could both send messages out Multicast which include "what" they are, and NetRemote could scoop these messages up and say "Oh, there is a Girder server at [ip] and MJB server at [ip]" such that even if the server pieces aren't multicast listening, the server can make the clients aware of what servers are available. This is obviously a step towards the "holy grail" of remote control, and something that isn't that far-fetched. Something that I think needs to wait until a stable 1.0 NetRemote, but something I think we -should- look into.

brockgr
March 10th, 2003, 07:07 PM
Ben

Your understanding of the network connections sounds like what I was thinking. "event" and "talk" channels - I like it.

One question about the quoted (") strings. I assume you are prepared to handle escaped quotes (\") and therefor escaped slashes (\\). Or will we have an arbitery restiction on the use of the quote character in labels?

I'll start coding this. It will be a .LUA "plugin" style file - with an otional add-in GML for debugging (can't access the OSD from LUA plugins).

Since this will be pure LUA, I'll try to make the Girder part optional. The non-windows people (Stewart??) may just want to run a LUA interperter on their platform, or embed the LUA code in their favourite language (like this (http://www.cis.upenn.edu/~cvogler/lua/luajava.html)).

Gavin

Ben S
March 10th, 2003, 08:26 PM
Sounds good Gavin. Yes, I will handle escaped characters (quotes, backslashes, carriage returns) via a backslash.

I'm going to make this an either/or right now, as it doesn't make sense to have a thread for standard "IEC" style feedback as well as lua style feedback.

I'm going to release 0.982 in a day or two, and then I will put support for this method into the Girder driver for the next release.

Do you agree we shouldn't base64 encode the image data? It will save us 1/3 of the throughput, and theoretically save some performance as no need to encode/decode.

This should really go far to alleviate the current bottleneck regarding feedback.

One question. How will your lua code handle the multithreaded issue of the socket within Girder? IE: If two events try to send info back to NetRemote. Right now, each one has it's own connection, and NetRemote has two threads handling it. Now we'll have one thread, so we need to make sure the data queues up correctly.

brockgr
March 10th, 2003, 11:35 PM
Ben,

Yep, I'm happy to drop Base64 if you are happy to read a set number of bytes - it was really there for when things seemed to be line delimited. Do you think it's worth having a trailer token so you know that you have read the binary data correctly. Or will you just drop the connection at the next unrecognised key word. IMHO, dropping the connection should be your first action on any type of chit-chat confusion (blocking, protocol errors etc).

As for multi-threading, I think I'm safe - I didn't realise that girder had multiple event threads, but I'm 99% sure that the LUA engine is single threaded so I can't possibly send to simultaneous events.

One feature suggestion - how about some user feedback from NR for the establishment of the two sockets. I kinda like the idea of a PCMCIA style - beep-boop sound. One tone for "event" channel connection, and another for accepting the "talk" channel. Could be visual otherwise - but then we run into skinning and stuff.

Gavin

Ben S
March 11th, 2003, 09:16 PM
No problem reading a set # of bytes. I'm doing this on the Base64 data right now, anyway.

I don't think the trailer token is neccessary, but I will allow a "null command" (bare \n) without dropping. Anything I don't understand I will handle by dropping the connection. That sounds like a decent way to handle it, so it doesn't get all kludged up.

I'm not sure if Girder has multiple event threads or not, I've always assumed it did, and assumed that Girder could post more than one message at a time through different threads to NEtRemote.

Beep-boop. :)

Good idea, I've been thinking about something like this for when it's communicating, as well. A flashing icon or something. Let me look into it. I'll see if I can beep-boop as well.