The No.1 Website for Pro Audio
 Search This Thread  Search This Forum  Search Reviews  Search Gear Database  Search Gear for sale  Search Gearslutz Go Advanced
Dante routing without Dante Controller is possible
Old 3rd July 2018
  #1
Here for the gear
Dante routing without Dante Controller is possible

I'm doing this on Arch Linux with a virtual machine running Windows 10 and Dante Controller. My goal is to have fully scriptable channel routing from Linux clients. It was trivial to capture some network traffic with wireshark and replay it with netcat to send commands to my Audinate AVIO adapters to route channels between devices.

For example, with 192.168.1.15 as the avio-output adapter:

# avio-input ch1 -> avio-output ch1 off
echo '2729001001da30140000000100000001' | xxd -r -p | nc -c -w1 -u 192.168.1.15 4440

# avio-input ch1 -> avio-output ch1 on
echo '2729002f02923010000001010001002000240000000000000000000000000000434831006176696f2d696e70757400' | xxd -r -p | nc -c -w1 -u 192.168.1.15 4440
Old 20th November 2018
  #2
Here for the gear
 

I am extremely interested in this. Do you have some additional example code available?
Old 3rd February 2019
  #3
Here for the gear
Quote:
Originally Posted by dpzmick View Post
I am extremely interested in this. Do you have some additional example code available?
I haven't done much more than make this enable/disable connections. I'll keep this thread updated if I expand on this (I do plan on doing that). The basic idea is to capture the packets and resend them; I always found that there was a prefix in the request that could be removed. The device name is used in the request too.

edit: I received a new Dante device, so I made a video demo while I was collecting packets for the commands to it. The avio input and output adapters have level controls within Dante Controller; I've scripted these now too.

Here is a list of the features I have working so far.

Port 8700:
  • Sample rate
  • Level control
  • Preferred Encoding

Port 4440:
  • Get/set subscriptions
  • Device latency
  • Set/reset channel name
  • Rename device

MDNS:
  • Read device encoding
  • Read device sample rate
  • Read device latency
  • Enumerate channel count
  • Device discovery
  • Device model
  • MAC address
  • Device manufacturer
  • Device version

TODO:
  • Read events
  • Set device IP
  • Signal active/inactive state
  • Device reboot / clear config
  • Pull-up/down setting
  • Unicast Delay Requests setting
  • Enable/disable AES67 mode
  • Read latency tab info

video: Scripting Dante — Routing commands
code: Scripting Dante — Routing commands

video: Scripting Dante — Level controls
code: Scripting Dante — Level controls

I used wireshark with a filter to capture packets sent from Dante Controller. The packet destination is always going to be the receiver (rows in Dante Controller), and the source is whatever computer you are using to click on the buttons in Dante Controller. In this example, my Windows VM is 192.168.1.138 and the avio output adapter is 192.168.1.30.

Code:
ip.dst == 192.168.1.30 && ip.src == 192.168.1.138
Once you do this, restart the capture (clear the screen of logged packets) and click the button to enable the connection anywhere in Dante Controller.
Right click the first packet logged and select copy -> bytes -> hex stream. You'll get a string like this:
Code:
001dc1501ec0525400c5c27108004500004b6
d8c00008011491dc0a8018ac0a8011ed96111
58003784412729002f0809301000000101000
1002000240000000000000000000000000000
434831006176696f2d696e70757400
I've added line-breaks so this isn't too long, but when you send this later it shouldn't have those. After all of the irrelevant confirmation packets are sent and settled, clear the packet log again and then click on the same connection in Dante Controller to remove the route you just added. Again, you want the first packet logged, and it will look something like this when the hex stream is copied:
Code:
001dc1501ec0525400c5c27108004500002c6
ca6000080114a22c0a8018ac0a8011ed96111
5800188422272900100800301400000001000
00001
Strip the packet header (in this example the data always starts with "272900" for every request).
Code:
2729002f08093010000001010001002000240
0000000000000000000000000004348310061
76696f2d696e70757400
Code:
27290010080030140000000100000001
Now you can send this data back yourself without Dante Controller. I'm using BSD netcat and xxd here for these examples. UDP port 4440. Don't use any line-breaks or spaces in the echo command.

On:
Code:
echo '001dc1501ec0525400c5c27108004500002c6ca6
000080114a22c0a8018ac0a8011ed961115800188
42227290010080030140000000100000001' | xxd -r -p | nc -w0 -u 192.168.1.30 4440
Off:
Code:
echo '2729002f0809301000000101000100200024
0000000000000000000000000000434831006176696f
2d696e70757400' | xxd -r -p | nc -w0 -u 192.168.1.30 4440
You can use the same payload for different receivers by changing only the IP address.

For the level controls, the requests needed to be sent on port 8700. Each of the devices had a unique prefix for all requests, while only the channel number and setting would change.
Code:
  bytes='ffff003403440000525400c5c2710000417564696e61746507271
00a0000000000010001000c001001020000000000
0100000002'
  echo "${bytes}" | xxd -r -p | nc -w0 -u $host 8700
In this example, 0100000002 is the only unique part of the request to this device. The first 01 is the channel number; so 01 or 02 in my case. The last number was the setting; 01 was the first selection and 05 was the last.

MDNS is used for device/service discovery and can be used to read the device config:
Code:
{
  "name": "avio-output._netaudio-arc._udp.local",
  "type": "TXT",
  "class": "IN",
  "flash": true,
  "ttl": 4500,
  "rdata": {
    "arcp_vers": "2.7.41",
    "arcp_min": "0.2.4",
    "router_vers": "4.0.1",
    "router_info": "DAO2",
    "mf": "Audinate",
    "model": "DAO2"
  }
},
{
  "name": "avio-input._netaudio-cmc._udp.local",
  "type": "TXT",
  "class": "IN",
  "flash": true,
  "ttl": 4500,
  "rdata": {
    "id": "001dc1fffe502b0a",
    "process": "0",
    "cmcp_vers": "1.2.0",
    "cmcp_min": "1.0.0",
    "server_vers": "4.0.2",
    "channels": "0x6000004d",
    "mf": "Audinate",
    "model": "DAI2"
  }
},
{
  "name": "[email protected]_netaudio-chan._udp.local",
  "type": "TXT",
  "class": "IN",
  "flash": true,
  "ttl": 3600,
  "rdata": {
    "txtvers": "2",
    "dbcp1": "0x1102",
    "dbcp": "0x1004",
    "id": "1",
    "rate": "48000",
    "en": "24",
    "pcm": "3 4",
    "enc": "24",
    "latency_ns": "1000000",
    "fpp": "16,16",
    "nchan": "2"
  }
}

Last edited by s00pcan; 3rd February 2019 at 09:05 PM.. Reason: added videos
Post Reply

Welcome to the Gearslutz Pro Audio Community!

Registration benefits include:
  • The ability to reply to and create new discussions
  • Access to members-only giveaways & competitions
  • Interact with VIP industry experts in our guest Q&As
  • Access to members-only sub forum discussions
  • Access to members-only Chat Room
  • Get INSTANT ACCESS to the world's best private pro audio Classifieds for only USD $20/year
  • Promote your eBay auctions and Reverb.com listings for free
  • Remove this message!
You need an account to post a reply. Create a username and password below and an account will be created and your post entered.


 
 
Slide to join now Processing…
Thread Tools
Search this Thread
Search this Thread:

Advanced Search
Forum Jump
Forum Jump