From 6ae73a994b15be73c01ae5d6835297bcff7baa91 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 1 May 2021 14:45:12 +0200 Subject: Basic kinet backend skeleton and analysis --- backends/Makefile | 8 +++-- backends/kinet.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ backends/kinet.h | 54 ++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 backends/kinet.c create mode 100644 backends/kinet.h diff --git a/backends/Makefile b/backends/Makefile index d815f84..5628b4b 100644 --- a/backends/Makefile +++ b/backends/Makefile @@ -2,9 +2,9 @@ # Backends that can only be built on Linux LINUX_BACKENDS = midi.so evdev.so # Backends that can only be built on Windows (mostly due to the .DLL extension) -WINDOWS_BACKENDS = artnet.dll osc.dll loopback.dll sacn.dll maweb.dll winmidi.dll openpixelcontrol.dll rtpmidi.dll wininput.dll visca.dll +WINDOWS_BACKENDS = artnet.dll osc.dll loopback.dll sacn.dll maweb.dll winmidi.dll openpixelcontrol.dll rtpmidi.dll wininput.dll visca.dll kinet.dll # Backends that can be built on any platform that can load .SO libraries -BACKENDS = artnet.so osc.so loopback.so sacn.so lua.so maweb.so jack.so openpixelcontrol.so python.so rtpmidi.so visca.so +BACKENDS = artnet.so osc.so loopback.so sacn.so lua.so maweb.so jack.so openpixelcontrol.so python.so rtpmidi.so visca.so kinet.so # Backends that require huge dependencies to be installed OPTIONAL_BACKENDS = ola.so # Backends that need to be built manually (but still should be included in the clean target) @@ -39,6 +39,10 @@ artnet.so: ADDITIONAL_OBJS += $(BACKEND_LIB) artnet.dll: ADDITIONAL_OBJS += $(BACKEND_LIB) artnet.dll: LDLIBS += -lws2_32 +kinet.so: ADDITIONAL_OBJS += $(BACKEND_LIB) +kinet.dll: ADDITIONAL_OBJS += $(BACKEND_LIB) +kinet.dll: LDLIBS += -lws2_32 + osc.so: ADDITIONAL_OBJS += $(BACKEND_LIB) osc.dll: ADDITIONAL_OBJS += $(BACKEND_LIB) osc.dll: LDLIBS += -lws2_32 diff --git a/backends/kinet.c b/backends/kinet.c new file mode 100644 index 0000000..df259cf --- /dev/null +++ b/backends/kinet.c @@ -0,0 +1,106 @@ +#define BACKEND_NAME "kinet" + +/* + * This protocol is largely undocumented. As a result, + * this backend may in some cases produce unintended + * output artifacts. + * + * Due to lack of consistent access to compliant hardware, + * testing is infrequent. If you are able to provide + * additional feedback or testing on compatible hardware, + * please notify the developers. + */ + +#include + +#include "libmmbackend.h" +#include "kinet.h" + +#define MAX_FDS 255 + +static struct { + size_t fds; + int* fd; +} global_cfg = { + 0 +}; + +/* + * TODO + * * detect mode + */ + +MM_PLUGIN_API int init(){ + backend kinet = { + .name = BACKEND_NAME, + .conf = kinet_configure, + .create = kinet_instance, + .conf_instance = kinet_configure_instance, + .channel = kinet_channel, + .handle = kinet_set, + .process = kinet_handle, + .start = kinet_start, + .shutdown = kinet_shutdown + }; + + //register backend + if(mm_backend_register(kinet)){ + LOG("Failed to register backend"); + return 1; + } + return 0; +} + +static int kinet_configure(char* option, char* value){ + //TODO + return 0; +} + +static int kinet_configure_instance(instance* inst, char* option, char* value){ + //TODO + return 0; +} + +static int kinet_instance(instance* inst){ + inst->impl = calloc(1, sizeof(kinet_instance_data)); + if(!inst->impl){ + LOG("Failed to allocate memory"); + return 1; + } + + return 0; +} + +static channel* kinet_channel(instance* inst, char* spec, uint8_t flags){ + //TODO + return NULL; +} + +static int kinet_set(instance* inst, size_t num, channel** c, channel_value* v){ + //TODO + return 0; +} + +static int kinet_handle(size_t num, managed_fd* fds){ + //TODO + return 0; +} + +static int kinet_start(size_t n, instance** inst){ + //TODO + return 0; +} + +static int kinet_shutdown(size_t n, instance** inst){ + size_t u; + kinet_instance_data* data = NULL; + + for(u = 0; u < n; u++){ + data = (kinet_instance_data*) inst[u]->impl; + free(inst[u]->impl); + inst[u]->impl = NULL; + } + + LOG("Backend shut down"); + return 0; +} diff --git a/backends/kinet.h b/backends/kinet.h new file mode 100644 index 0000000..a93c576 --- /dev/null +++ b/backends/kinet.h @@ -0,0 +1,54 @@ +#include "midimonster.h" + +MM_PLUGIN_API int init(); +static int kinet_configure(char* option, char* value); +static int kinet_configure_instance(instance* inst, char* option, char* value); +static int kinet_instance(instance* inst); +static channel* kinet_channel(instance* inst, char* spec, uint8_t flags); +static int kinet_set(instance* inst, size_t num, channel** c, channel_value* v); +static int kinet_handle(size_t num, managed_fd* fds); +static int kinet_start(size_t n, instance** inst); +static int kinet_shutdown(size_t n, instance** inst); + +#define KINET_PORT "6038" +#define KINET_MAGIC htobe32(0x0401dc4a) + +enum { + kinet_op_dmx = 0x0101, //v1 + kinet_op_out = 0x0108 //v2 +}; + +//As a byproduct of the sparse documentation, a lot of these +//fields are educated guesses. + +#pragma pack(push, 1) +typedef struct /*_kinet_header*/ { + uint8_t magic[4]; //04 01 dc 4a + uint16_t version; //01 00 + uint16_t op; //08 01 + uint32_t seq; //00 00 00 00 + uint8_t output_port; //00 //FIXME verify this / usage? + uint8_t pad; //00 + uint16_t flags; //00 00 +} kinet_frame_hdr; + +typedef struct /*_kinet_dmx*/ { + uint32_t offset; + uint8_t universe; + uint8_t startcode; //FIXME test this + uint8_t data[512]; +} kinet_dmx; + +typedef struct /*_kinet_out*/ { + uint8_t port; + uint8_t padding; + uint16_t flags; + uint16_t length; + uint16_t code; + uint8_t data[512]; +} kinet_out; +#pragma pack(pop) + +typedef struct /*_kinet_instance_data*/ { + size_t n; +} kinet_instance_data; -- cgit v1.2.3