Skip to content

Latest commit

 

History

History
174 lines (119 loc) · 9.17 KB

README.md

File metadata and controls

174 lines (119 loc) · 9.17 KB

OSCulate

About

OSCulate is an embedded C++ program written for the sole purpose of creating an ETCnomad keyboard that communicates over OSC, rather than over USB HID. At the moment, OSCulate only supports keyboards, but I plan to extend support to buttons and other sorts of input devices.

Supported Devices

  • Teensy 4.1
  • ETC Eos Family Software v3.1+

If your device or firmware is not yet on here, please see the Future Plans section for more information.

Backstory

As an ETCnomad user, I wanted to make my ETCnomad keyboard, based on Josh Spurgers' writeup here, a bit more robust in how it communicates with ETCnomad. Currently, the Cherry SPOS keyboards have a few downsides when used as an Eos Keyboard. In order to program the keyboard, each key can be either a single key or a key macro.

Unfortunately for us, the key macros send the entire key series at once, and do not work with long pressing and holding down the key. For example, the Eos keyboard shortcut for the data key is ctrl D. When setting a key on the Cherry SPOS to use the key macro of ctrl D, the cherry board sends key down events for both ctrl and D, but then immediately following sends key up events for ctrl and D, without ever waiting for the trigger key to be released.

In order to fix this, and ensure that this fix could work on any computer without needing to install specific software, I knew I needed to process the commands before they even went to the console.

I also wanted to improve the communication, as communicating like a keyboard means that pressing whatever key on said keyboard goes to the focused program. We could even implement hardware macros if we wanted!1 This is not ideal, as pressing live while having the wrong program selected results in sending f1 to a program that isn't Eos. This is far from ideal, as we want our Eos keyboard to be functional all of the time.

Thankfully, Eos has support for this, by using the OSC protocol to communicate.

The OSC Protocol

Eos family software supports all of the forms of OSC protocols: UDP, TCP, and even OSC over USB Serial.

In order to make our input more robust, we want to communicate over USB or TCP. Unlike USB or TCP, UDP is not reliant as it does not contain native assurances our messages have arrived. With TCP, we have built in retransmission support for our commands, in the event they were dropped by the network.

OSC Communication

OSC over Serial

Not implemented.

OSC over UDP

While you can technically use OSC with TCP, this library does implement direct support for sending OSC commands with UDP as it is considered a footgun.

OSC over TCP

OSC supports being sent over a TCP connection, with a similar format to a UDP packet. Both OSC v1.0 and OSC v1.1 are supported, with the option currently set in config.h.

Networking

In order to further ensure that OSCulate can be robust without needing to be a pain point of configuration or other issues with programming, OSCulate attempts to make no assumptions about the network or console environments it is working on.

DHCP and Fallback IP Addressing

On boot, and any time OSCulate is connected to a network, it will first attempt to receive an IP from a DHCP server. If it fails to receive an IP within about 15 seconds, it will fallback to a hardcoded IP address on the subnet 10.101.0.0, with a subnet mask of 255.255.0.0. This is the recommended subnet configuration as suggested by Eos themselves, which should be supported by all networks, unless they've been changed by an installer.

Console Discovery

Once the network interface is operational and has an IP address (either by DHCP or by static fallback), we attempt to find any consoles existing on the network with the Visible to Remotes setting enabled.

Eos has quite a few undocumented portions of code, however, with this functional on Eos 2.x and 3.x, it is safe to say that it is unchanging for a long, long, time. That said, I am aware this may not always function on newer versions, and so we fall back to a fallback IP when we cannot find an IP.

Due to simplicity, this library is currently using the undocumented APIs that exist for the aRFR mobile apps.

A more detailed write-up is accessible in the Advanced section, under Usage of console discovery

Advanced

Usage of Undocumented Eos Features

The two usages of undocumented features implemented as of now are:

  • use of the mobile apps OSC server
  • use of the undocumented Eos OSC discovery server

Both of these undocumented features can be bypassed with official means, but the negatives would far outweigh the positives.

Usage of Mobile Apps API

The mobile app clients for Eos connect to an undocumented OSC server running at port 3036, which is running version 1.0 for backwards compatibility. It is always accepting connections, but only processes OSC commands if the Allow Remotes setting is turned on in the console.

This does the following:

  • Pros
    • always a v1.0 OSC TCP server when enabled
    • there is only one toggle in the console for this connection
    • the same behaviour on version 2.9 and 3.x
  • Cons
    • undocumented server

There are two main options we can switch to, though both also have their pros and cons.

  • 3032
    • Pros
      • official recommendation
      • lots of customization options
    • Cons
      • requires the user to set settings in their console, or in the code here
      • can be any port at all
      • not always be available
      • can be either OSC v1.0 or v1.1
      • requires several settings to be enabled
  • 3037
    • Pros
      • when enabled, always a v1.1 OSC TCP server
      • there is only one toggle for this server
      • same settings control this enpoint as 3036
    • Cons
      • only supported since Eos 3.1+

This library wants to be as functional as it can be. As such, it currently uses port 3036, as that has the longest backwards compatability, and is easiest to develop for while supporting both Eos 2.9 and 3.X. A future version may add support for attempting port 3037 connections before falling back to port 3036.

Usage of Console Discovery

ETC consoles run a listener for a discovery request, sent over an UDP OSC request, for the visible to remotes option. If it is enabled, the listener will also respond.

This seems to exists for the official mobile apps to automatically show existing consoles on the network. However, this API can, in my opinion, be considered somewhat stable and public, as the Luminosus Eos Edition used the same API to detect Eos consoles on the network.

Future Plans

Not all of these ideas below will come to fruition, but this is a good starting point for what I have planned.

  • process OSC discovery replies
    • allow us to determine console version ahead of connection
  • process commands we receive from Eos during normal operation
  • version detection of the Eos console.
    • support staging_mode vs scroll_lock for the same key.
    • Will effectively add support for Eos 2.9
  • fallback to OSC Serial
  • teensy 4.0, (build flag to remove networking related code)
    • OSC Serial support required beforehand
  • implement our own OSC API. Useful for when we're running without a serial console and want to get diagnostics.
  • SLP protocol support to determine what computers are running Eos,
  • support for additional ports

ETC Trademark Disclosure

Electronic Theatre Controls has trademarks on the following:

  • Eos
  • ETCnomad
  • ETC

Usage of their trademark does not signify an endorsement, or partnership, or relation of any kind. This is not official ETC software.

Trademark and patent info: etcconnect.com/IP

Footnotes

  1. support for hardware macros is not implemented as this does not extend well when moving to a different input mechanism. The goal of OSCulate is to make a third party keyboard have a robust input, similar to a dedicated faceplate or programming wing. It is not to give it additional features that a console does not have. Not yet, anyways.