You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
index.js line 74 - /info/getLocations checks for definition of type parameter, which breaks older STB compatibility. Comments note that this may be erroneous.
#2
Open
Numbski opened this issue
Oct 19, 2020
· 0 comments
For the sake of not repeating a whole lot of typing, I'm going to link a downstream project issue that I opened for this before I understood that the problem was actually upstream:
In very, very brief terms - older set top boxes are compatible (mostly), but they do not support the type argument to /info/getLocations, and depending on how pervasive this is in the code, it could come up elsewhere. Using one of my own STBs as an example:
pi@homebridge:~/scripts/directv$ curl http://172.16.30.79:8080/info/getLocations | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 195 100 195 0 0 1772 0 --:--:-- --:--:-- --:--:-- 1772
{
"locations": [
{
"clientAddr": "0",
"locationName": "LIVING ROOM"
}
],
"status": {
"code": 200,
"commandResult": 0,
"msg": "OK.",
"query": "/info/getLocations"
}
}
Note that "type" isn't being sent. Now let's look at what directv-remote attempts to send to that receiver:
Which makes sense, because if you poll /info/getOptions, you get this back:
pi@homebridge:~/scripts/directv$ curl http://172.16.30.79:8080/info/getOptions | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5873 100 5873 0 0 20607 0 --:--:-- --:--:-- --:--:-- 20679
{
"options": [
{
"command": "/info/getLocations",
"description": "List of available client locations. Warning: This command may change or be disabled in the future.",
"formControls": [],
"urlParameters": [
{
"isRequired": false,
"name": "wrapper",
"type": "string"
},
{
"isRequired": false,
"name": "callback",
"type": "string"
}
]
},
*snip*
It only supports wrapper and callback. Neither is required. So if we bounce back over to your code, we have this block:
// "List of available client locations."
// Returns an array of the networked set top boxes
// type is an optional parameter
// the docs label it as 'int'
// only 0 and 1 aren't *Forbidden*
// i'm not sure what the difference is yet,
// but 1 shows more of my wireless Genie STBs
this.getLocations = function(type, callback){
var path = '/info/getLocations';
var options = {
hostname: this.IP_ADDRESS,
port: 8080,
path: path
};
if (typeof type !== 'undefined') {
options.path = buildQueryString(options.path, { type: type });
}
makeRequest(options, callbackHandler(callback));
};
So type is "optional", but then a bit further down we check to make sure type isn't undefined. If it is, we don't do anything. If it isn't, we makeRequest(). Best I can tell, there's a line missing to call buildQueryString without the type parameter, probably inside of an else something like this (not a nodeJS dev, please correct if I have syntactical mistakes!):
if (typeof type !== 'undefined') {
options.path = buildQueryString(options.path, { type: type });
}
else {
options.path = buildQueryString(options.path);
}
That way we build the query string no matter what, and then makeRequest should handle the rest from there.
For the sake of completeness, here is the full output of /info/getOptions. I can make a cursory scan to see if this "type" business is present anywhere else, but it is a comparison that will be challenging without output of a more modern set of hardware. My suspicion is that on older hardware, type wasn't defined. On newer genie-era hardware type 0 is likely a standalone STB, and type 1 is a genie with child units. Either way, I think my solution solves for that. Again, not a nodeJS dev - need to go spelunking on my filesystem and see if I can apply this fix and see it work.
{
"options": [
{
"command": "/info/getLocations",
"description": "List of available client locations. Warning: This command may change or be disabled in the future.",
"formControls": [],
"urlParameters": [
{
"isRequired": false,
"name": "wrapper",
"type": "string"
},
{
"isRequired": false,
"name": "callback",
"type": "string"
}
]
},
{
"command": "/info/getSerialNum",
"description": "STB serial number. Warning: This command may change or be disabled in the future.",
"formControls": [],
"urlParameters": [
{
"isRequired": false,
"name": "wrapper",
"type": "string"
},
{
"isRequired": false,
"name": "callback",
"type": "string"
},
{
"isRequired": false,
"name": "clientAddr",
"type": "string"
}
]
},
{
"command": "/info/getVersion",
"description": "Set-top-box and SHEF information. Warning: This command may change or be disabled in the future.",
"formControls": [],
"urlParameters": [
{
"isRequired": false,
"name": "wrapper",
"type": "string"
},
{
"isRequired": false,
"name": "callback",
"type": "string"
}
]
},
{
"command": "/info/mode",
"description": "Set-top-box mode. Warning: This command may change or be disabled in the future.",
"formControls": [],
"urlParameters": [
{
"isRequired": false,
"name": "wrapper",
"type": "string"
},
{
"isRequired": false,
"name": "callback",
"type": "string"
},
{
"isRequired": false,
"name": "clientAddr",
"type": "string"
}
]
},
{
"command": "/remote/processKey",
"description": "Process a key request from the remote control. Warning: This command may change or be disabled in the future.",
"formControls": [],
"urlParameters": [
{
"isRequired": false,
"name": "wrapper",
"type": "string"
},
{
"isRequired": false,
"name": "callback",
"type": "string"
},
{
"isRequired": false,
"name": "clientAddr",
"type": "string"
},
{
"isRequired": false,
"name": "hold",
"type": "string"
},
{
"isRequired": true,
"name": "key",
"type": "string"
}
]
},
{
"command": "/serial/processCommand",
"description": "Process a command request from remote control. Warning: This command may change or be disabled in the future.",
"formControls": [],
"urlParameters": [
{
"isRequired": false,
"name": "wrapper",
"type": "string"
},
{
"isRequired": false,
"name": "callback",
"type": "string"
},
{
"isRequired": true,
"name": "cmd",
"type": "hex"
}
]
},
{
"command": "/tv/getProgInfo",
"description": "Program information of specified channel at current or specific time. Warning: This command may change or be disabled in the future.",
"formControls": [],
"urlParameters": [
{
"isRequired": false,
"name": "wrapper",
"type": "string"
},
{
"isRequired": false,
"name": "minor",
"type": "int"
},
{
"isRequired": false,
"name": "callback",
"type": "string"
},
{
"isRequired": true,
"name": "major",
"type": "int"
},
{
"isRequired": false,
"name": "clientAddr",
"type": "string"
},
{
"isRequired": false,
"name": "time",
"type": "long"
}
]
},
{
"command": "/tv/getTuned",
"description": "Information about the currently viewed program. Warning: This command may change or be disabled in the future.",
"formControls": [],
"urlParameters": [
{
"isRequired": false,
"name": "wrapper",
"type": "string"
},
{
"isRequired": false,
"name": "callback",
"type": "string"
},
{
"isRequired": false,
"name": "videoWindow",
"type": "string"
},
{
"isRequired": false,
"name": "clientAddr",
"type": "string"
}
]
},
{
"command": "/tv/tune",
"description": "Tune to a channel. Warning: This command may change or be disabled in the future.",
"formControls": [],
"urlParameters": [
{
"isRequired": false,
"name": "wrapper",
"type": "string"
},
{
"isRequired": false,
"name": "minor",
"type": "int"
},
{
"isRequired": false,
"name": "callback",
"type": "string"
},
{
"isRequired": true,
"name": "major",
"type": "int"
},
{
"isRequired": false,
"name": "source",
"type": "int"
},
{
"isRequired": false,
"name": "clientAddr",
"type": "string"
}
]
}
],
"status": {
"code": 200,
"commandResult": 0,
"msg": "OK.",
"query": "/info/getOptions"
}
}
The text was updated successfully, but these errors were encountered:
This is pending a fix upstream with DirecTV-remote to properly handle an
undefined "type" when calling getLocations. Please see:
ToddGreenfield#17
and
cmrust/directv-remote#2
For the sake of not repeating a whole lot of typing, I'm going to link a downstream project issue that I opened for this before I understood that the problem was actually upstream:
ToddGreenfield/homebridge-directv#17
In very, very brief terms - older set top boxes are compatible (mostly), but they do not support the
type
argument to /info/getLocations, and depending on how pervasive this is in the code, it could come up elsewhere. Using one of my own STBs as an example:Note that "type" isn't being sent. Now let's look at what directv-remote attempts to send to that receiver:
/info/getLocations?type=1
If I attempt to do that, here's what happens:
Which makes sense, because if you poll /info/getOptions, you get this back:
It only supports wrapper and callback. Neither is required. So if we bounce back over to your code, we have this block:
So type is "optional", but then a bit further down we check to make sure type isn't undefined. If it is, we don't do anything. If it isn't, we makeRequest(). Best I can tell, there's a line missing to call buildQueryString without the type parameter, probably inside of an else something like this (not a nodeJS dev, please correct if I have syntactical mistakes!):
That way we build the query string no matter what, and then makeRequest should handle the rest from there.
For the sake of completeness, here is the full output of /info/getOptions. I can make a cursory scan to see if this "type" business is present anywhere else, but it is a comparison that will be challenging without output of a more modern set of hardware. My suspicion is that on older hardware, type wasn't defined. On newer genie-era hardware type 0 is likely a standalone STB, and type 1 is a genie with child units. Either way, I think my solution solves for that. Again, not a nodeJS dev - need to go spelunking on my filesystem and see if I can apply this fix and see it work.
The text was updated successfully, but these errors were encountered: