TiVo Community Forum banner
  • TiVoCommunity.com Ambassador Program Now Open! >>> Click Here

Discovering the iPad interface

159K views 373 replies 47 participants last post by  moyekj 
#1 ·
Let's see how much I can do without actually having an iPad...

Nmap against a Series 3:

PORT STATE SERVICE
80/tcp open http
443/tcp open https
2190/tcp open unknown
2191/tcp open unknown
3791/tcp open unknown
31339/tcp open unknown

Nmap against a Premiere running 14.7RC7:

PORT STATE SERVICE
80/tcp open http
443/tcp open https
1390/tcp open iclpv-sc
1393/tcp open iclpv-nls
1400/tcp open cadkey-tablet
1410/tcp open hiq
1413/tcp open innosys-acl
2190/tcp open unknown
2191/tcp open unknown
8430/tcp open unknown
31339/tcp open unknown

FWIW, port 8430 disappeared when I repeated the scan.

Avahi Zeroconf Browser lists some new services, Premiere only:

_tivo-mindrpc._tcp
_tivo-device._tcp

These are in addition to the existing _tivo-remote._tcp, etc. that other TiVos report. According to this, the "mindrpc" service runs on port 1413. ("tivo-device" just shows as port 80.)

Perhaps the mindrpc service works like mind.tivo.com?
 
See less See more
#77 ·
#78 ·
It's pretty clear that RPC is just part of the story though. I think the iPad is also communicating with tivo.com servers to get a lot of information and also perhaps using the traditional HMO to communicate with the TiVos as well.

Typically RPC search queries directly to the TiVo only return 1 result and are highly targeted/filtered. For example, you can't get list of all recordings on the TiVo, but you can get additional details on particular shows. When you search for "scheduled" recordings without a filter you only get the first in To Do list as a response. i.e. When using this protocol you should already be armed with specific information about existing and/or scheduled recordings which are obtained with alternate means.

Note also for example that a show 'delete' does not seem to happen through this protocol. The only relevant RPC related to delete I found was:
111637-1229-1-recordingUpdate-recordingUpdate.txt
i.e. Just information that a specific show was deleted. The actual delete itself was performed with a different method, probably using different port and protocol.
 
#79 ·
It's pretty clear that RPC is just part of the story though. I think the iPad is also communicating with tivo.com servers to get a lot of information and also perhaps using the traditional HMO to communicate with the TiVos as well.
I'm not certain of that yet. I think it's just complicated, nothing is completely done in one RPC.

Typically RPC search queries directly to the TiVo only return 1 result and are highly targeted/filtered. For example, you can't get list of all recordings on the TiVo
Plenty of RPCs response is an "idSequence". I think you just need to take those IDs and fire off another call to get their details. Anyway, this is one of the areas I'd expect to concentrate; getting the list of stuff on the TiVo and interacting with it (play, delete, etc.) is one of the primary nice features to add on top of the apps currently available for Android. (Which all seem to use IRCODE.)

Clearly my docs are missing something, because I don't have any idSequence responses documented. But they're there in the traces. It's gonna take a lot of work to read through all the possible responses and see where I'm missing things. Requests seem to omit optional parameters all the time, making finding them extra tricky.

Note also for example that a show 'delete' does not seem to happen through this protocol. The only relevant RPC related to delete I found was:
111637-1229-1-recordingUpdate-recordingUpdate.txt
i.e. Just information that a specific show was deleted. The actual delete itself was performed with a different method, probably using different port and protocol.
That is the request to perform the delete. The response is 111637-1229-2-response-success.txt -- success, that recording ( tivo:rc.181929 ) was deleted.
 
#80 ·
That is the request to perform the delete. The response is 111637-1229-2-response-success.txt -- success, that recording ( tivo:rc.181929 ) was deleted.
Ah, yes that should have been obvious - given that there is a response to go along with it. What threw me off was the state='deleted' which implied it already had happened. I was indeed able to delete a show using that method, and oddly enough it worked just using bodyId='-' (i.e. no need for tsn even though bodyId is a required argument). Now to focus next on how to obtain recording id's...
 
#81 ·
Very simply, to get recordings in My Shows it is:
req = RpcRequest('recordingFolderItemSearch', bodyId='-')
(One can use 'orderBy' argument to change the order)

Also, I am glad to see I was wrong about response being only 1 item at a time. Above seems to return a full list (including folders and #items per folder).
 
#82 ·
Here's a fun (if difficult to read) image to explain the request and response types:

http://img820.imageshack.us/img820/3053/maprequeststoresponsesf.png

You can see that subscriptionSearch could give a subscriptionList, or an idSequence. Then recordingSearch could give recordingList or idSequence, also recordingFolderItemSearch could give recordingFolderItemList or idSequence.

I think you see where I'm going. I happen to see a recordingFolderItemSearch that sets "format": "idSequence", gets back

Code:
{
  "isBottom": false, 
  "isTop": false, 
  "objectIdAndType": [
    "94873", 
    "871425", 
    "870665", 
    "37169", 
    "120769", 
    "46006", 
    "57822", 
    "36231", 
    "36432", 
    "35665", 
    "35648", 
    "603352", 
    "35662", 
    "38264", 
    "35739", 
    "1", 
    "0"
  ], 
  "type": "idSequence"
}
Then very soon issues a recordingFolderItemSearch of

Code:
{
  "orderBy": [
    "startTime"
  ], 
  "bodyId": "tsn:7460001905F9871", 
  "objectIdAndType": [
    "94873", 
    "871425", 
    "870665", 
    "37169", 
    "120769"
  ], 
  "note": [
    "recordingForChildRecordingId"
  ], 
  "type": "recordingFolderItemSearch", 
  "responseTemplate": [...]
}
Notice how those are the first five in the list? It issues one RPC (in this case) to see what the groups are, then another to see what the contents of (some of those) groups are. There's more RPC(s) later to dig into the list of what the recordings are, if one of these results is actually a group. (I see items and groups with lengths mixed into this response. Exactly what you'd see on the "My Shows" section of the TiVo itself, if it's set to show groups, depending on what recordings you have.)
 
#83 ·
Two new things to report. One, the proof-of-concept script, updated to speak the newer protocol on port 1413:
https://gist.github.com/1009602#file_remote2.py

Two, the documentation I had previously mentioned:
https://docs.google.com/document/pub?id=1e4ymm7ROwmW6co2pKENjANGT5xM00VzmzybZ4u8yDE8

I'd love to know more about what all the RPCs are and how they relate, but I'm still working on figuring that all out.
Thanks. It's obvious that you took (and are taking) a good chunk of time getting this information together. I have little doubt that an iPad like app will be developed based on your efforts.
 
#84 ·
Haven't had much time to play around with this but did so a little last night. arantius, this is a TiVo gold mine you have uncovered. It doesn't take much effort to get complete "My Shows" and "To Do" lists which I have prototypes for. No doubt season pass management, etc. can also be implemented. I haven't even touched possibilities with HME, show searching etc.

This discovery basically unlocks and makes available a big chunk of the database on the Premiere that was not available previously directly from Premiere. It's akin to having a hacked Premiere without the need for hacking.
 
#85 ·
Haven't had much time to play around with this but did so a little last night. arantius, this is a TiVo gold mine you have uncovered. It doesn't take much effort to get complete "My Shows" and "To Do" lists which I have prototypes for. No doubt season pass management, etc. can also be implemented. I haven't even touched possibilities with HME, show searching etc.

This discovery basically unlocks and makes available a big chunk of the database on the Premiere that was not available previously directly from Premiere. It's akin to having a hacked Premiere without the need for hacking.
I am absolutely awestruck by the amount of information that is now available. Using the remote.py script, I've been adding in the discovered RequestTypes as functions in the Remote Class, similar to the following:

Code:
    ...
    # bodyConfigSearch
    def bodyConfigSearch(self):
        req = RpcRequest('bodyConfigSearch', 
                         bodyId='-')
        self.Write(req)
        result = self.Read()
        for item in result:
            print item
        print result['response']
        print " "
        print result
        print " "

    # channelSearch
    def channelSearch(self):
        req = RpcRequest('channelSearch',
                         noLimit='true', 
                         isReceived='false') 
        self.Write(req)
        result = self.Read()
        for item in result:
            print item
        print result['response']
        print " "
        print result
        print " "
    ...
and just simply calling them to see what can be gleaned from my own Premiere:

Code:
    ...
    remote = Remote()

    print 'bodyConfigSearch'
    remote.bodyConfigSearch()

    print 'channelSearch'
    remote.channelSearch()

   ...
Oh. My. God.

My mind is reeling with potential applications that can come from this. I can seriously see elimination of (TiVo) meta-generators that rely on IMDB and TheTVDB. Show and movie cover art and image links can be found, hardware information (userDiskSize, userDiskUsed), software information (hasScheduler(?), softwareVersion, parentalControlsState, clipOverlapping, etc.), Series information, Episode information, the list goes on and on. And I've only defined the first four RequestTypes! It makes me wonder what else is buried under the covers. What would be icing on the cake would be a "QuerySchema" request, that outputs ALL of the RequestTypes and their options, as well as output definitions.
 
#88 ·
I'm not a fan of hyperbole, but arantius' time and effort (I think) was monumental! There's a lot to go through, but I encourage downloading the "Request/Responses" zip found in this post: http://www.tivocommunity.com/tivo-vb/showthread.php?p=8556511#post8556511

If you do get the zip, this file is an example of a collectionSearch: 61706-32-2-response-contentList.txt, that I think would provide an ideal set of data for a new meta-generator. Bah, here's the content of the file:

Code:
MRPC/2 76 2928
Raw Packet=MRPC/2 76 2928
Content-Type: application/json
IsFinal: true
RpcId: 32
Type: response

{
  "content": [
    {
      "category": [
        {
          "image": [
            {
              "width": 360, 
              "imageUrl": "http://i.tivo.com/images-static/bravo/genre-backgrounds/showcaseBanner/Drama.jpg", 
              "type": "image", 
              "imageType": "showcaseBanner", 
              "height": 270
            }, 
            {
              "width": 180, 
              "imageUrl": "http://i.tivo.com/images-static/bravo/genre-backgrounds/moviePoster/Drama.jpg", 
              "type": "image", 
              "imageType": "moviePoster", 
              "height": 270
            }
          ], 
          "displayRank": 0, 
          "type": "category", 
          "label": "Drama"
        }, 
        {
          "displayRank": 1, 
          "type": "category", 
          "label": "TV Show"
        }
      ], 
      "collectionType": "series", 
      "seasonNumber": 4, 
      "description": "Gossip flies about Caroline and a man (Gil Gerard) building her kitchen in exchange for room and board.", 
      "episodic": true, 
      "collectionId": "tivo:cl.19284", 
      "contentId": "tivo:ct.127876", 
      "image": [
        {
          "width": 139, 
          "imageUrl": "http://i.tivo.com/images-production/bravo/banner-med/dd/a7/dda739d69d9893b079ee4479043e9dea.jpg", 
          "type": "image", 
          "imageType": "showcaseBanner", 
          "height": 104
        }, 
        {
          "width": 200, 
          "imageUrl": "http://i.tivo.com/images-production/bravo/banner-lg/dd/a7/dda739d69d9893b079ee4479043e9dea.jpg", 
          "type": "image", 
          "imageType": "showcaseBanner", 
          "height": 150
        }
      ], 
      "episodeNum": [
        4
      ], 
      "originalAirYear": 1977, 
      "credit": [
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Landon", 
          "first": "Michael"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Grassle", 
          "first": "Karen"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Gilbert", 
          "first": "Melissa"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Anderson", 
          "first": "Melissa"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Swenson", 
          "first": "Karl"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Bull", 
          "first": "Richard"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "MacGregor", 
          "first": "Katherine"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Arngrim", 
          "first": "Alison"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Gilbert", 
          "first": "Jonathan"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Hagen", 
          "first": "Kevin"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Greer", 
          "first": "Dabbs"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Stewart", 
          "first": "Charlotte"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Olsen", 
          "first": "Merlin"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Laborteaux", 
          "first": "Patrick"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Parady", 
          "first": "Hersha"
        }, 
        {
          "role": "guestStar", 
          "type": "credit", 
          "last": "Gerard", 
          "first": "Gil"
        }, 
        {
          "role": "guestStar", 
          "type": "credit", 
          "last": "Baddeley", 
          "first": "Hermione"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Greenbush", 
          "first": "Lindsay"
        }, 
        {
          "role": "actor", 
          "type": "credit", 
          "last": "Greenbush", 
          "first": "Sidney"
        }, 
        {
          "role": "writer", 
          "type": "credit", 
          "last": "Heinemann", 
          "first": "Arthur"
        }, 
        {
          "role": "director", 
          "type": "credit", 
          "last": "Claxton", 
          "first": "William F."
        }
      ], 
      "title": "Little House on the Prairie", 
      "subtitle": "The Handyman", 
      "type": "content", 
      "tvRating": "pg"
    }
  ], 
  "type": "contentList"
}
Note that it contains: a couple "imageUrl"s, "seasonNumber", "episodeNum", "originalAirYear", "title" (Series title), and "subtitle" (Episode title), not to mention "description" and "role" for cast and crew, all handy/interesting information. Other than the images, I believe all the other information is local. Although the Request looks a bit daunting, I think the payoff is well worth the effort. Yessir, I like it! :up:
 
#90 ·
I love the API documentation, great work arantius. I will definitely try to contribute to it. There are so many things I could do with this, projects I could make, the possibilities are literally endless.

I never posted sample code on here because in my sample, I tried using a random X-ApplicationSessionId, which I now know is not a good idea. :p

(For some reason I never got notified when someone posted on here :/)
 
#91 ·
I guess the next question is there anything us non programmers can do to help?
Post ideas about what ya want! :D

I have a feeling moyekj will have a java version of something out before long. I'm struggling with (personally) interpreting JSON nomenclature, and getting useful Requests put together. For example, when querying the (local) To Do List, I can only get the first item in the list. I'm sure there's something to say "get the rest", but for the time being, I'm just trying to get a grasp of all the things that can be had, and will worry about the details later....
 
#92 ·
I love the API documentation, great work arantius. I will definitely try to contribute to it. There are so many things I could do with this, projects I could make, the possibilities are literally endless.

I never posted sample code on here because in my sample, I tried using a random X-ApplicationSessionId, which I now know is not a good idea. :p

(For some reason I never got notified when someone posted on here :/)
Nice to hear! More eyes on it could/should mean quicker development of stuff!
 
#93 ·
Post ideas about what ya want! :D
LOL
For example, does this mean potentially we could actually transfer and automatically rename shows so they end up in the SxxExx format in the name since the current way is hit or miss on season and episode information even though the Premiere screen will display it properly?
 
#94 ·
LOL
For example, does this mean potentially we could actually transfer and automatically rename shows so they end up in the SxxExx format in the name since the current way is hit or miss on season and episode information even though the Premiere screen will display it properly?
With proper formatting of the information retrieved from the Premiere, I would think that yes, SxxExx could be added to the subtitle (episode name). I'll have to see if Search capabilities extend to sources like Netflix or Amazon for movies and/or documentaries.
 
#95 ·
OK, got past the To Do List search only returning one item by including a "count=" option:
Code:
    def ToDoSearch(self):
        req = RpcRequest('recordingSearch', 
                         levelOfDetail='low', 
                         bodyId='-', 
                         count='50',
                         state=['scheduled'])
Setting a count too high results in:
Code:
{'debug': '', 'text': 'Count is out of range. 1 <= count <= 50', 'code': 'badArgument', 'type': 'error'}
I'm looking for some type of "Anchor" statement that could continue listing beyond the first 50 items.

Adding an offset seems to do the trick:
Code:
    def ToDoSearch(self):
        req = RpcRequest('recordingSearch', 
                         levelOfDetail='low', 
                         bodyId='-', 
                         count='50',
                         offset='50',
                         state=['scheduled'])
 
#96 ·
The thing I'm most interested in is correcting rotten bits of the native tivo interface, like by having a cron job to download schedule info off the tivo and schedule recording of alternate showings of episodes you missed due to a conflict (but which are now not "new" anymore, so the tivo won't automatically record them).

Or a way to correct the "new" flag by recording the descriptions of the shows and scheduling recordings for any show with a new description and cancelling recordings of shows marked new that have a description I already remember.

I can also imagine using the tivo to get schedule info, then using it in a myth TV setup to get an additional tuner that will at least work on unencrypted channels.
 
#97 ·
I never posted sample code on here because in my sample, I tried using a random X-ApplicationSessionId, which I now know is not a good idea.
I'm generally mystified by that value yet. It just seemed strange that they seemed to be large numbers in a small range, for what samples I had, so I just did random within that range.

(For some reason I never got notified when someone posted on here :/)
As far as I can tell, (depending on options) you get one notification, then no more until you visit the site (thread?).
 
#98 ·
Just got to "uiNavigate". Nice. Set a URI gathered from "uiDestinationInstanceSearch", and instantly jump to that (HME) app, just like hitting LiveTV or TiVo button.

URIs:
Code:
Amazon:             x-tivo:hme:uuid:35FE011C-3850-2228-FBC5-1B9EDBBE5863
Blockbuster:        x-tivo:hme:uuid:63ED0C3D-D49C-9602-C322-E0A3D3EA5A3D
Browse Web Videos:  x-tivo:hme:uuid:19452283-D00B-C411-595D-447ABF62F37C
Browse Web Videos:  x-tivo:hme:uuid:6784571A-016C-8A46-DF2F-FD842D78006F
Fandango:           x-tivo:hme:uuid:B9DDBECF-BC6D-5E33-388A-4CF840068D79
Music Choice:       x-tivo:hme:uuid:7FDF1BEB-AF92-B8B6-6269-FAE44C8F887D
Netflix:            x-tivo:hme:uuid:7edeb291-0db8-487f-b842-6b97bc71ad9a
One True Media:     x-tivo:hme:uuid:D1AF7BED-325E-5E6E-B087-72381C92D077
Swivel:             x-tivo:hme:uuid:2BD40EF7-D9D2-3CD4-0130-6C18855CE898
TiVoCast RSS:       x-tivo:hme:uuid:863cb78f-efdd-4106-b572-51733983dc76
Youtube:            x-tivo:hme:uuid:9AA364C9-CF8A-1E1D-B50F-CC65C40D4A96
The function:
Code:
    def uiNavigate(self):
        req = RpcRequest('uiNavigate',
                         uri='x-tivo:hme:uuid:2BD40EF7-D9D2-3CD4-0130-6C18855CE898',
                         bodyId='-')
        self.Write(req)
 
This is an older thread, you may not receive a response, and could be reviving an old thread. Please consider creating a new thread.
Top