So I managed to pick up one of these on eBay for cheap. It supports FrameChannel, Flickr and Picasa so I thought I’d give a go to supporting it on FrameAlbum.
I will be digging into the technical issues of adding support for this frame to the FrameAlbum service. I’ll be using terms such as ‘DNS server’, ‘XML’, ‘packet capture’ and ‘negatively charged penguin bladders’ so if these are unknown/offensive to you read on at your peril.
The initial setup was easy enough — it found my WiFi network and connected with no worries. It does have a manual network setup option but it oddly includes only an IP address and default router (gateway); it excludes the DNS server setting. This eliminates using the FrameAlbum DNS server on the frame itself so I had to fallback to configuring the WiFi access point to offer it as part of the DHCP setup. Bummer.
What is this ‘eframe’ of which you speak?
I happened to have a packet capture running while the frame was starting up and along with the usual DHCP stuff was this:
broadcast to UDP/21900. A quick consult with my all-knowning friend Google yielded this. Apparently this is a protocol used by eFrame frames to download photos from a PC. I wonder if the Viewsonic frame is a rebranded eFrame device? I’ll leave that for another day.
It grabs a NTP time sync from pool.ntp.org, nice. It then starts sending TCP connection requests to the DNS port of the B root domain server (22.214.171.124). It does this every 5 seconds – whoa. I’m guessing it uses this info. to determine that it has internet connectivity but wow – that it seriously uncool behavior.
For the purpose of the following discussion I’ll use the term ‘service’ to refer to FrameChannel/FrameAlbum; it’s just easier to type. 😉
This frame doesn’t use the typical method to associate itself with the service. Most frames will connect to the service and provide a frameID (usually the frame’s MAC address) in the request. If the frame is known (and registered) on the service it will provide the frame’s XML feed. If the frame is unknown/unregistered it will simply send a feed containing a single graphic that provides an ‘activation code’. This code is then entered by the user into the service’s website thereby associating that user with that frame.
The Viewsonic frame requires the user to enter his/her service username and a PIN into the frame using a rather awkward on-screen keyboard and remote. (BTW, if you don’t have the remote it is VERY tedious to enter this information and you will NOT be able to edit or remove existing entries). In the case of FrameAlbum the username is the name you choose during registration (not your email address). The PIN is a slightly different matter.
The service automatically generates the PIN for you when you add a new frame to your account. It is embedded in the ‘Feed URL’ information displayed when you view the details of your frame. For example, if your Feed URL is “
http://rss.framealbum.com/feed.php?fid=123456&pin=99887” your frame’s PIN is 99887.
Because the Viewsonic frame requires you to enter your account information manually you will need to ‘Add a new frame’ on the FrameAlbum website before you can configure the frame. This will generate the necessary PIN that you need to setup the account on the frame.
Let the packet capture begin!
Once the FrameAlbum account is configured you can then return to the Main Menu and choose ‘Photos’ and then ‘FrameChannel’. Oddly, you are now offered a folder labeled ‘friends’ that you must select. Then you are presented with a folder labeled with your FrameChannel username. I’m guessing that it’s possible to configure the frame with multiple service accounts but I did not test that. When you select the folder with your username the real fun begins.
I had started a packet capture before selecting the folder. Once the folder is selected the frame did the following:
DNS query www.framechannel.com
GET /feeds/feed.php?user=USERNAME&pin=PINCODE Host: www.framechannel.com
The server reponds with the XML and then the frame repeats the request again — whhhhhaaaa? Ohhhhkayy.
A few things straight off;
- It is making the requests to ‘www.framechannel.com’ rather than ‘rss.framechannel.com’. This is not all that unusual, D-Link frames for example contact ‘dlink.framechannel.com’. But it does throw a small curve-ball into my server setup (not configured to offer RSS feeds from that domain).
- It uses the ‘/feeds/’ URL segment rather than the more common ‘/feed/’.
- It is not providing a frameID
- The request does not specify the ‘HTTP/1.1’ version but yet includes a ‘Host:’ header in the request. Rather uncool.
Since it is not providing the ‘HTTP/1.1’ attribute on the GET action the server treats it as a 1.0 client and ignores the ‘Host:’ header and sends it to the ‘default’ Apache vhost. This was a problem for me as I have a few other websites hosted on the same server as FrameAlbum and it depends on the Host header to figure out which one the client wants to reach. Sooo… I had add a few ‘Alias’ statements to my default vhost config to point it at the FrameAlbum RSS feed code. This also took care of the ‘/feeds/’ vs. ‘/feed/’ item. The HTTP 1.0 stuff will come back to bite us again later.
I updated the feed generator to handle the username and PIN request format. Not a big deal unless you misread your notes and thought that the parmameter was ‘username’ rather than ‘user’ – DOH!
Your feed, sir…
Here is what is sent to the as-yet-unregistered frame:
<?xml version="1.0" encoding="utf-8" ?> <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/" xmlns:frameuserinfo="http://www.framechannel.com/feeds/frameuserinfo/" xmlns:tsmx="http://www.thinkingscreenmedia.com/tsmx/" > <channel> <title>FrameAlbum content for inactive_frame</title> <link>http://www.framealbum.com</link> <description> Channel for inactive frame </description> <ttl>60</ttl> <frameuserinfo:firstname>-</frameuserinfo:firstname> <frameuserinfo:lastname>-</frameuserinfo:lastname> <frameuserinfo:username>inactive_frame</frameuserinfo:username> <frameuserinfo:unregistered>FALSE</frameuserinfo:unregistered> <item> <title>FrameAlbum Info</title> <link>http://image.framealbum.com/-info.jpg</link> <category>FrameAlbum Info</category> <description><img src="http://image.framealbum.com/-info.jpg"></description> <pubDate>Thu, 23 Jun 2011 17:04:46 -0400</pubDate> <guid isPermaLink="false">30f8b8d1-80af-38e7-8616-b3e793dc289b</guid> <media:content url="http://image.framealbum.com/-info.jpg" type="image/jpeg" height="480" width="800" duration="3" /> <media:thumbnail url="http://image.framealbum.com/-info.jpg" height="60" width="60" /> <tsmx:sourcelink></tsmx:sourcelink> </item> </channel> </rss>
Meanwhile, the frame has been displaying ‘Loading photos…’. After a bit a thumbnail of the graphic included in the feed is displayed. Sweet!
I select the thumbnail using the arrow buttons on the remote and hit ‘OK’. The screen changes to ‘Loading…’.
I be confused…
At this point the frame does something very odd…
DNS QUERY <BLANK>
So after a bit of head scratching it occurs to me that the
Much better, the frame is now doing a DNS QUERY on image.framealbum.com — cool. So here comes the HTTP request for the image file:
GET /**-info.jpg HTTP/1.0 User-Agent: Bsocket Accept: */* Host: image.framealbum.com Connection: Keep-Alive
Are you kidding me? Where was all this during the RSS feed request? Oy! At any rate my server begins send the image file to the frame. Sadly, after only a few packets the frame sends a TCP RESET to the server and terminates the transfer. It re-issues the DNS QUERY and then the GET request. The server starts sending it again and again the frame sends a TCP RESET. Rinse, repeat.
Apparently the frames TCP receive buffer is overflowing and triggering the connection reset. Why it is overflowing is still a mystery.
That’s enough for one post. Stay tuned.