aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2020-04-14 00:16:48 +0200
committercbdev <cb@cbcdn.com>2020-04-14 00:16:48 +0200
commit462b409d3d1fa16fcab0c7f8b475bb8d8e8b3e90 (patch)
tree929f69d672f76b0e9fe5513a061fcf2abf1680e7
parentf9ae5d3a21f520380b3f761b71e211e6c438227a (diff)
parent4b991a31eed602070d241e77e98d62e06d647289 (diff)
downloadmidimonster-462b409d3d1fa16fcab0c7f8b475bb8d8e8b3e90.tar.gz
midimonster-462b409d3d1fa16fcab0c7f8b475bb8d8e8b3e90.tar.bz2
midimonster-462b409d3d1fa16fcab0c7f8b475bb8d8e8b3e90.zip
Merge branch 'master' of ssh://github.com/cbdevnet/midimonster
-rw-r--r--backends/osc.c105
-rwxr-xr-xinstaller.sh27
2 files changed, 89 insertions, 43 deletions
diff --git a/backends/osc.c b/backends/osc.c
index f40f3f5..72a7b50 100644
--- a/backends/osc.c
+++ b/backends/osc.c
@@ -10,6 +10,7 @@
/*
* TODO
* ping method
+ * bundle output
*/
#define osc_align(a) ((((a) / 4) + (((a) % 4) ? 1 : 0)) * 4)
@@ -720,7 +721,7 @@ static int osc_set(instance* inst, size_t num, channel** c, channel_value* v){
//sanity check
if(ident.fields.channel >= data->channels
|| ident.fields.parameter >= data->channel[ident.fields.channel].params){
- LOG("Channel identifier out of range");
+ LOG("Channel identifier out of range, possibly an output channel was not pre-configured");
return 1;
}
@@ -757,7 +758,7 @@ static int osc_set(instance* inst, size_t num, channel** c, channel_value* v){
return rv;
}
-static int osc_process_packet(instance* inst, char* local_path, char* format, uint8_t* payload, size_t payload_len){
+static int osc_process_message(instance* inst, char* local_path, char* format, uint8_t* payload, size_t payload_len){
osc_instance_data* data = (osc_instance_data*) inst->impl;
size_t c, p, offset = 0;
osc_parameter_value min, max, cur;
@@ -809,15 +810,82 @@ static int osc_process_packet(instance* inst, char* local_path, char* format, ui
return 0;
}
+static int osc_process_packet(instance* inst, uint8_t* buffer, size_t len){
+ osc_instance_data* data = (osc_instance_data*) inst->impl;
+ size_t offset = 0, message_length = len;
+ char* osc_local = NULL, *osc_fmt = NULL;
+ uint8_t* osc_data = NULL;
+ uint32_t* bundle_size = NULL;
+ uint8_t decode_bundle = 0;
+
+ //bundles need at least a header and timestamp
+ if(len >= 16 && !memcmp(buffer, "#bundle\0", 8)){
+ decode_bundle = 1;
+ offset = 16;
+ }
+
+ do{
+ if(decode_bundle){
+ if(len - offset < 4){
+ LOGPF("Failed to decode bundle size: %" PRIsize_t " bytes left at %" PRIsize_t " of %" PRIsize_t, len - offset, offset, len);
+ break;
+ }
+ bundle_size = (uint32_t*) (buffer + offset);
+ message_length = be32toh(*bundle_size);
+ DBGPF("Next bundle entry has %" PRIsize_t " bytes", message_length);
+ offset += 4;
+
+ if(len - offset < message_length){
+ LOGPF("Bundle member size out of bounds: %" PRIsize_t " bytes left", len - offset);
+ break;
+ }
+ }
+
+ //check for recursive bundles
+ if(message_length >= 16 && !memcmp(buffer + offset, "#bundle\0", 8)){
+ DBGPF("Recursing into sub-bundle of size %" PRIsize_t " on %s", message_length, inst->name);
+ osc_process_packet(inst, buffer + offset, message_length);
+ }
+ //ignore messages if root filter active
+ else if(data->root && strncmp((char*) (buffer + offset), data->root, min(message_length, strlen(data->root)))){
+ DBGPF("Ignoring message due to active root filter %s: data is for %s", data->root, buffer + offset);
+ }
+ else{
+ //FIXME all these accesses should be checked against message_length
+ osc_local = (char*) (buffer + offset + (data->root ? strlen(data->root) : 0));
+ osc_fmt = (char*) (buffer + offset + osc_align(strlen((char*) (buffer + offset)) + 1));
+
+ if(*osc_fmt != ','){
+ //invalid format string
+ LOGPF("Invalid format string in packet for instance %s: %s", inst->name, osc_fmt);
+ }
+ else{
+ osc_fmt++;
+
+ if(osc_global_config.detect){
+ LOGPF("Incoming data: Path %s.%s Format %s", inst->name, osc_local, osc_fmt);
+ }
+
+ osc_data = (uint8_t*) osc_fmt + (osc_align(strlen(osc_fmt) + 2) - 1);
+ if(osc_process_message(inst, osc_local, osc_fmt, osc_data, message_length - (osc_data - (uint8_t*) buffer))){
+ LOGPF("Failed to process OSC message on %s", inst->name);
+ }
+ }
+ }
+
+ offset += message_length;
+ }
+ while(offset < len);
+
+ return 0;
+}
+
static int osc_handle(size_t num, managed_fd* fds){
size_t fd;
- char recv_buf[OSC_RECV_BUF];
+ uint8_t recv_buf[OSC_RECV_BUF];
instance* inst = NULL;
osc_instance_data* data = NULL;
ssize_t bytes_read = 0;
- char* osc_fmt = NULL;
- char* osc_local = NULL;
- uint8_t* osc_data = NULL;
for(fd = 0; fd < num; fd++){
inst = (instance*) fds[fd].impl;
@@ -841,30 +909,7 @@ static int osc_handle(size_t num, managed_fd* fds){
break;
}
- if(data->root && strncmp(recv_buf, data->root, min(bytes_read, strlen(data->root)))){
- //ignore packet for different root
- continue;
- }
- osc_local = recv_buf + (data->root ? strlen(data->root) : 0);
-
- osc_fmt = recv_buf + osc_align(strlen(recv_buf) + 1);
- if(*osc_fmt != ','){
- //invalid format string
- LOGPF("Invalid format string in packet for instance %s", inst->name);
- continue;
- }
- osc_fmt++;
-
- if(osc_global_config.detect){
- LOGPF("Incoming data: Path %s.%s Format %s", inst->name, osc_local, osc_fmt);
- }
-
- //FIXME check supplied data length
- osc_data = (uint8_t*) osc_fmt + (osc_align(strlen(osc_fmt) + 2) - 1);
-
- if(osc_process_packet(inst, osc_local, osc_fmt, osc_data, bytes_read - (osc_data - (uint8_t*) recv_buf))){
- return 1;
- }
+ osc_process_packet(inst, recv_buf, bytes_read);
} while(bytes_read > 0);
#ifdef _WIN32
diff --git a/installer.sh b/installer.sh
index 111c783..66eef99 100755
--- a/installer.sh
+++ b/installer.sh
@@ -71,7 +71,7 @@ ARGS(){
-fu|--forceupdate)
UPDATER_FORCE="1"
;;
- --install-updater)
+ --install-updater|--selfupdate)
NIGHTLY=1 prepare_repo
install_script
exit 0
@@ -83,19 +83,20 @@ ARGS(){
-h|--help|*)
assign_defaults
printf "${bold}Usage:${normal} ${0} ${c_green}[OPTIONS]${normal}"
- printf "\n\t${c_green}--prefix${normal} ${c_red}<path>${normal}\t\tSet the installation prefix\t\t${c_mag}Default:${normal} ${dim}%s${normal}" "$VAR_PREFIX"
- printf "\n\t${c_green}--plugins${normal} ${c_red}<path>${normal}\tSet the plugin install path\t\t${c_mag}Default:${normal} ${dim}%s${normal}" "$VAR_PLUGINS"
- printf "\n\t${c_green}--defcfg${normal} ${c_red}<path>${normal}\t\tSet the default configuration path\t${c_mag}Default:${normal} ${dim}%s${normal}" "$VAR_DEFAULT_CFG"
- printf "\n\t${c_green}--examples${normal} ${c_red}<path>${normal}\tSet the path for example configurations\t${c_mag}Default:${normal} ${dim}%s${normal}\n" "$VAR_EXAMPLE_CFGS"
- printf "\n\t${c_green}--dev${normal}\t\t\t\tInstall nightly version"
- printf "\n\t${c_green}-d, --default${normal}\t\t\tUse default values to install"
- printf "\n\t${c_green}-fu, --forceupdate${normal}\t\tForce the updater to update without a version check"
- printf "\n\t${c_green}--install-updater${normal}\t\tInstall the updater (Run with midimonster-updater)"
- printf "\n\t${c_green}--install-dependencies${normal}\t\tInstall dependencies and exit"
- printf "\n\t${c_green}-h, --help${normal}\t\t\tShow this message and exit"
- printf "\n\t${uline}${bold}${c_mag}Each argument can be overwritten by another, the last one is used!${normal}\n"
+ printf "\n\t${c_green}--prefix=${normal}${c_red}<path>${normal}\t\tSet the installation prefix.\t\t${c_mag}Default:${normal} ${dim}%s${normal}" "$VAR_PREFIX"
+ printf "\n\t${c_green}--plugins=${normal}${c_red}<path>${normal}\tSet the plugin install path.\t\t${c_mag}Default:${normal} ${dim}%s${normal}" "$VAR_PLUGINS"
+ printf "\n\t${c_green}--defcfg=${normal}${c_red}<path>${normal}\t\tSet the default configuration path.\t${c_mag}Default:${normal} ${dim}%s${normal}" "$VAR_DEFAULT_CFG"
+ printf "\n\t${c_green}--examples=${normal}${c_red}<path>${normal}\tSet the path for example configurations.\t${c_mag}Default:${normal} ${dim}%s${normal}\n" "$VAR_EXAMPLE_CFGS"
+ printf "\n\t${c_green}--dev${normal}\t\t\tInstall nightly version."
+ printf "\n\t${c_green}-d,\t--default${normal}\tUse default values to install."
+ printf "\n\t${c_green}-fu,\t--forceupdate${normal}\tForce the updater to update without a version check."
+ printf "\n\t${c_green}--selfupdate${normal}\t\tUpdates this script to the newest version and exit."
+ printf "\n\t${c_green}--install-updater${normal}\tInstall the updater (Run with midimonster-updater) and exit."
+ printf "\n\t${c_green}--install-dependencies${normal}\tInstall dependencies and exit"
+ printf "\n\t${c_green}-h,\t--help${normal}\t\tShow this message and exit."
+ printf "\n\t${uline}${bold}${c_mag}Each argument can be overwritten by another, the last one is used!.${normal}\n"
rmdir "$tmp_path"
- exit 1
+ exit 0
;;
esac
shift