Hacking multimedia equipment with PowerShell

I just started on a new part of my home automation project, controlling my receiver (Onkyo TX-NR616).

I thought that this might be a good opportunity to do a “walk-through” on how to create a script for something that clearly was not meant to be controlled with PowerShell, in this case a surround receiver.

The basic methods and principles used here should be applicable to more or less anything you want to automate and I hope someone might find it useful!

Small disclaimer:
I take no responsibility in how you use the information in this post, make sure you know what you are doing! Even though any damage to a receiver or other equipment should be unlikely, I wont give you any guarantees…

So… The steps involved are basically:

  1. Figure out how the item (website, device, software…) is controlled. Does it have a documented API? Is it using REST? Website? Mobile app?
  2. Figure out how to utilize this with PowerShell. If it is a REST-based API, you are lucky, websites or webservices are also highly automatable (always check ToS before doing it though…), if it has a mobile app or similar, it most definitely is using some sort of API which may or may not be easy to figure out.
  3. I usually build a simple script to start doing some testing. Once I figured out how the API works, I turn that into an advanced function.
  4. Enjoy doing yet another thing with the blue console of wonder!

I will now try to describe how I used this basic approach to control my receiver!


So, how is it controlled?

In this case, I knew there was a mobile app available, and therefore, there must be some kind of API. After some research I found out that they are using something called “Integra Serial Communication Protocol”, or eISCP as it is called when used over an ethernet connection.

After some “intense googling” I found some documentation of this protocol at http://blog.siewert.net/?p=37.

Now we know it has an API and we can figure out how it works!

But what if we didn’t have any documentation? Or if we just want to use a few commands (like power on/off), do we really need to learn the complete documentation?

That depends, sometimes you can just “copy -> paste” the commands from a trace. That will be described under the next part of this post; “Using a network trace”.


Using a network trace
Documentation obviously helps a lot, but if we pretend there was none available, should you just give up? Of course not! 🙂

One approach if that is the case is to basically just sniff the network traffic. You can do this with whatever tool you prefer, two free examples are Wireshark and Microsoft Network Monitor.

If you can find a windows application for the device, that helps since you can just sniff your local network traffic. Another alternative if you want to stick to a windows computer but all you can find to control your devices is a mobile app, you could try to run routing and remote access (or internet connection sharing) to just make the traffic go through your PC, which then acts as a router. After that, your network analyzer/sniffer should pick up the traffic, which hopefully will not be encrypted (there are ways of solving that too, but we’ll stick to the simpler scenarios here…).

When you got this ready, just start your sniffer and your application used to control your device, and record whatever command you want to be able to automate.

This is a screenshot of a Wireshark trace recording a “power on” command sent to the Onkyo receiver:

wireshark_capture

Right click the first package sent to receiver and choose “follow TCP stream”. That makes it a bit easier to see what is happening, it looks like this:
follow_trace

The colouring makes it easier to see what gets sent to the receiver and what gets sent back, the first command (light red colouring above) shows what the app sent to turn on the receiver, the dots just represent “non printable characters”, so the command looks somewhat like “ISCP !1PWR01” which does seem like a “power on” command!

Now select “C Arrays” instead of Hex Dump, select the package you want and copy the text, like this:

follow_trace_c_arrays

You now have the whole command needed to turn the device on! Since what you will be sending is byte arrays and not HEX, you need to convert the HEX to Bytes instead. To do this, open a PowerShell prompt, paste the text you copied, add a pipe and write “% { [BYTE]$_ }”, press enter two times and they are converted! Should look like this:
convert_to_bytes

Those bytes are what you need to send using the Send-method of System.Net.Sockets.Socket. More on that follows under the next part of this post!


Sending TCP streams with PowerShell
We now know what we should send, but how?
There are many examples around on how to do this, I will post one that at least I thought was fairly straight forward.

The code looks like this: (Credit to this thread for getting me started!)

# First we need to specify the port and IP-address to device. Both are visible in the wireshark trace above
[int] $Port = 60128
$DeviceAddress = [system.net.IPAddress]::Parse("192.168.1.5")

# Create the IP Endpoint
$Endpoint = New-Object System.Net.IPEndPoint $DeviceAddress, $Port

# Create a socket
$Saddrf = [System.Net.Sockets.AddressFamily]::InterNetwork
$Stype = [System.Net.Sockets.SocketType]::Stream
$Ptype = [System.Net.Sockets.ProtocolType]::TCP
$Socket = New-Object System.Net.Sockets.Socket $saddrf, $stype, $ptype
$Socket.TTL = 32

# Connect the socket to the endpoint
$Socket.Connect($Endpoint)

# Create the byte array
[Byte[]] $ByteArray = 73,83,67,80,0,0,0,16,0,0,0,8,1,0,0,0,33,49,80,87,82,48,49,13,10

# And send it!
$Sent = $Socket.Send($ByteArray)

And the receiver turns on! This code lacks quite a lot, like a method of reading the reply, closing the socket, error handling etc., but it will hopefully give you an idea on how to tackle something like this! If you want something slightly more polished, check the last part of this post…

But I want to do a lot of different things, not just turn it on/off!
I will fix a module for controlling Onkyo receivers as soon as I get more time, in the meantime I have made a “quick and dirty” advanced function that allows you to add the command to a parameter. To give you an idea:
example_of_cmdlet

If you look in the documentation I linked to above, you will probably figure out the commands for more or less anything. I have tested this on my receiver to for example use Spotify, change volume, change inputs and so on…

The module will probably include something like this function to enable a wider range of commands, but will also have cmdlets prepared for powering on, selecting different inputs (including subcategories under “Network”).

This function should just be considered an example on how you can do something like this with PowerShell, and was made since most of you might not be using Onkyo-receivers but still would like some sample code.

The code is available here.

7 thoughts on “Hacking multimedia equipment with PowerShell

  1. Caleb Clapp

    Hi

    I came upon this and am doing similar things through a home automation controller caller ISY by Universal Devices. Here’s a thread: http://forum.universal-devices.com/topic/12963-onkyointegra-eiscp-binary-strings-to-control-your-onkyo/#entry106111

    I have one question: I would like to assign keypad buttons and also the numbers on my harmony remote to specific Onkyo “Favorites” and/or Tine-in Radio presets. Do you know if one can select a favorite or preset directly?

    Reply
    1. Anders Post author

      Hi, nice to know there are others 😉 Sadly, I dont know if that is possible. I think you have to send a series of commands to accomplish that.

      But if you find out how, I’d love to know!

      Reply
  2. Sveni_Lee

    I came upon you page while I’m searching for a solution to integrate my Onkyo into my home-automation.
    I’ve the Onkyo Remote3 and I would need the part of discovering my “Home-Media” od the Onkyo.
    But I could not find out the command to receive all subfolders like in the App.
    So when I read your post it should be possible to sniff the comand to the Onkyo and the Answer, right?
    but how could I do this… “you could try to run routing and remote access (or internet connection sharing) to just make the traffic go through your PC”

    maybe you could give me a hint…

    Reply
    1. Anders Post author

      I definitely think you can sniff the commands out and reverse engineer it, however, it requires you to be able to somehow sniff the traffic between your phone and the Onkyo, which could be a bit tricky (all traffic is local). If you can find a PC program of an app that can do the same thing, it would be easier (then you can just use for example Wireshark to sniff the traffic internally in the PC).

      However, I’m thinking the list command might be the same for most services under the NET section. Did you check the linked xls-file that documents the protocol? (this one) Check under the “CMND (NET USB)” tab, row 71. Maybe that’s where the magic happens? (not sure though, haven’t tested that myself)

      Reply
  3. Sveni_Lee

    thanks for you fast reply.
    okay will see what is possible… my AVM fritzbox should be able to sbiffle the network, there is a hidden feature.
    the NLS didn’t do the trick caus it replay only 0-9 items but if you have more it will not shown…

    thanks

    Reply

Leave a Reply to Caleb Clapp Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.