int osc_i_handler(const char *path, const char *types, lo_arg **argv, int argc, void *msg, void *user_data) { assert(argv); assert(argc == 1); int i = argv[0]->i; if (i == 1234) { printf("osc_i_handler received 1234 at /osc/i\n"); message_count++; } else if (i == 2000) { lo_timetag tt; lo_timetag_now(&tt); timed_start = timetag_to_secs(tt); timed_count = 1; } else if (2000 < i && i < 2010) { lo_timetag tt; lo_timetag_now(&tt); double now = timetag_to_secs(tt); printf("osc_i_handler received %d at elapsed %g\n", i, now - timed_start); i -= 2000; assert(i == timed_count); assert(small(timed_start + i * 0.1 - now)); timed_count++; } else { assert(0); // unexpected message } return 0; }
static int _msg_handler (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *data) { FILE *file = data; uint8_t *buf; size_t size; lo_timetag now; lo_message _msg = msg; if (!is_bundle) { lo_timetag_now (&now); bundle = lo_bundle_new (now); } if (is_bundle) _msg = lo_message_clone (msg); lo_bundle_add_message (bundle, path, _msg); if (!is_bundle) { buf = lo_bundle_serialise (bundle, NULL, &size); lo_bundle_free (bundle); bundle = NULL; fwrite (buf, size, sizeof (uint8_t), file); fflush (file); free (buf); } return 0; }
foreign_t now(term_t sec, term_t frac) { lo_timetag ts; int64_t s, f; lo_timetag_now(&ts); s=ts.sec; f=ts.frac; return PL_unify_int64(sec,s) && PL_unify_int64(frac,f); }
static int _bundle_start_handler (lo_timetag time, void *data) { if ( (time.sec == LO_TT_IMMEDIATE.sec) && (time.frac == LO_TT_IMMEDIATE.frac) ) lo_timetag_now (&time); bundle = lo_bundle_new (time); //FIXME handle nested bundles is_bundle++; }
void mdev_timetag_now(mapper_device dev, mapper_timetag_t *timetag) { if (!dev) return; // first get current time from system clock // adjust using rate and offset from mapping network sync lo_timetag_now((lo_timetag*)timetag); mapper_timetag_add_seconds(timetag, dev->admin->clock.offset); }
void nfosc_stop() { int i; if (!running) return; running = false; if( main_thread ) pthread_detach(main_thread); main_thread = NULL; lo_bundle osc_bundle = lo_bundle_new(LO_TT_IMMEDIATE); for (i=0;i<buffer_size;i++) { lo_message del_message = lo_message_new(); lo_message_add_int32(del_message, tag_buffer[i].device_id); lo_message_add_int32(del_message, tag_buffer[i].symbol_id); lo_message_add_int32(del_message, tag_buffer[i].type_id); lo_message_add_string(del_message, tag_buffer[i].uid_str); lo_bundle_add_message(osc_bundle, "/nfosc/del", del_message); if (verbose) printf("del %d %d %d %s\n",tag_buffer[i].session_id,tag_buffer[i].symbol_id,tag_buffer[i].type_id,tag_buffer[i].uid_str); } lo_timetag frame_time; lo_timetag_now (&frame_time); for (int dev=0;dev<no_devices;dev++) { if (pnd[dev]==NULL) continue; lo_message frm_message = lo_message_new(); lo_message_add_int32(frm_message, -1); lo_message_add_timetag(frm_message, frame_time); lo_message_add_int32(frm_message, 0); // sensor dim if (device_count>1) sprintf(source_string, "NFOSC:%d",dev); lo_message_add_string(frm_message, source_string); // source name lo_bundle_add_message(osc_bundle, "/tuio2/frm", frm_message); lo_message sid_message = lo_message_new(); lo_bundle_add_message(osc_bundle, "/tuio2/alv", sid_message); } int ret = lo_send_bundle(target, osc_bundle); if(ret == -1) { fprintf(stderr, "an OSC error occured: %s\n", lo_address_errstr(target)); exit(1); } for (int dev=0;dev<no_devices;dev++) { if (pnd[dev]!=NULL) { printf("closing NFC reader #%d: %s\n",dev,nfc_device_get_name(pnd[dev])); nfc_close(pnd[dev]); } } nfc_exit(context); write_database(); }
void loop() { int i = 0; printf("Loading devices...\n"); while (i >= 0 && !done) { for (i=0; i<5; i++) mdev_poll(devices[i], 0); lo_timetag_now(&system_time); if (system_time.sec != last_update) { last_update = system_time.sec; if (ready) { for (i=0; i<5; i++) { mdev_timetag_now(devices[i], &device_times[i]); } // calculate standard deviation double mean = 0; for (i=0; i<5; i++) { mean += mapper_timetag_get_double(device_times[i]); } mean /= 5; double difference_aggregate = 0; for (i=0; i<5; i++) { difference_aggregate += powf(mapper_timetag_get_double(device_times[i]) - mean, 2); } // print current system time and device diffs printf("%f", (double)system_time.sec + (double)system_time.frac * 0.00000000023283064365); for (i=0; i<5; i++) { printf(" | %f", mapper_timetag_difference(system_time, device_times[i])); } printf(" | %f", sqrtf(difference_aggregate / 5)); printf("\n"); } else { int count = 0; for (i=0; i<5; i++) { count += mdev_ready(devices[i]); } if (count >= 5) { printf("\nSYSTEM TIME ***** | OFFSETS *****\n"); for (i=0; i<5; i++) { // Give each device clock a random starting offset devices[i]->admin->clock.offset = (rand() % 100) - 50; } ready = 1; } } } usleep(10 * 1000); } }
int main(int argc, const char * argv[]) { int tcpflag = 1; printf("Usage: lo_bndlsend [u] (u means use UDP)\n"); if (argc == 2) { tcpflag = (strchr(argv[1], 'u') == NULL); } printf("tcpflag %d\n", tcpflag); sleep(2); // allow some time for server to start client = lo_address_new_with_proto(tcpflag ? LO_TCP : LO_UDP, "localhost", "8100"); printf("client: %p\n", client); char s[128]; lo_timetag now; lo_timetag_now(&now); lo_timetag timetag; for (int i = 9; i >= 5; i--) { // make the bundle timetag_add(&timetag, now, 2 + i * 0.1); lo_bundle bndl = lo_bundle_new(timetag); // make first message sprintf(s, "an arbitrary string at 2.%d", i); lo_message msg1 = make_message(1000 + i, s); // add the message to the bundle lo_bundle_add_message(bndl, "/xyz/msg1", msg1); // make second message sprintf(s, "another arbitrary string at 2.%d", i); lo_message msg2 = make_message(2000 + i, s); // add the message to the bundle lo_bundle_add_message(bndl, "/abcdefg/msg2", msg2); // send it lo_send_bundle(client, bndl); } send_nested(now, 3.0, 0.0, 3000); send_nested(now, 3.1, 3.2, 4000); sleep(1); // make sure messages go out lo_address_free(client); sleep(1); // time to clean up socketsa printf("OSCSEND DONE\n"); return 0; }
/* returns the time in seconds until the next scheduled event */ double lo_server_next_event_delay(lo_server s) { if (s->queued) { lo_timetag now; double delay; lo_timetag_now(&now); delay = lo_timetag_diff(((queued_msg_list *)s->queued)->ts, now); delay = delay > 100.0 ? 100.0 : delay; delay = delay < 0.0 ? 0.0 : delay; return delay; } return 100.0; }
int jitter_handler(const char *path, const char *types, lo_arg **argv, int argc, lo_message data, void *user_data) { lo_timetag now; float jitter; lo_timetag_now(&now); jitter = fabs(lo_timetag_diff(now, argv[0]->t)); jitter_count++; //printf("jitter: %f\n", jitter); printf("%d expected: %x:%x received %x:%x\n", argv[1]->i, argv[0]->t.sec, argv[0]->t.frac, now.sec, now.frac); jitter_total += jitter; if (jitter > jitter_max) jitter_max = jitter; if (jitter < jitter_min) jitter_min = jitter; return 0; }
/* TODO: Bundle messages together that happen in the same call to poll(). */ void text_write_value(mapper_signal msig, void *v, mapper_timetag_t *tt) { int i; char str[1024], *path = str; msig_full_name(msig, path, 1024); if (path[0]=='/') path ++; while (path[0] && path[0]!='/') path ++; lo_timetag now; lo_timetag_now(&now); mapper_db_signal mprop = msig_properties(msig); if (!tt || !tt->sec) fprintf(output_file, "%u %u %s %c ", now.sec, now.frac, path, mprop->type); else fprintf(output_file, "%u %u %s %c ", tt->sec, tt->frac, path, mprop->type); if (mprop->type == 'i') { for (i=0; i<mprop->length; i++) fprintf(output_file, " %d", ((int*)v)[i]); } else if (mprop->type == 'f') { for (i=0; i<mprop->length; i++) fprintf(output_file, " %g", ((float*)v)[i]); } fprintf(output_file, "\n"); fflush(output_file); if (now.sec > last_write.sec) { printf("."); fflush(stdout); last_write = now; } }
EXPORT bool getRemoteMachinesAvailable(map<string, pair<string, int> >* machineList) { if (gDNS && gDNS->fLocker.Lock()) { for(map<string, member>::iterator it=gDNS->fClients.begin(); it != gDNS->fClients.end(); it++){ member iterMem = it->second; lo_timetag now; lo_timetag_now(&now); // If the server machine did not send a message for 3 secondes, it is considered disconnected if((now.sec - iterMem.timetag.sec) < 3){ // Decompose HostName to have Name, Ip and Port of service string serviceNameCpy(iterMem.hostname); int pos = serviceNameCpy.find("._"); string remainingString = serviceNameCpy.substr(pos+2, string::npos); pos = remainingString.find("._"); string serviceIP = remainingString.substr(0, pos); string hostName = remainingString.substr(pos+2, string::npos); int pos2 = serviceIP.find(":"); string ipAddr = serviceIP.substr(0, pos2); string port = serviceIP.substr(pos2+1, string::npos); (*machineList)[hostName] = make_pair(ipAddr, atoi(port.c_str())); } } gDNS->fLocker.Unlock(); return true; } else { return false; } }
/* TODO: Bundle messages together that happen in the same call to poll(). */ void text_write_generic(const char *path, const char *types, lo_message m) { lo_timetag now; lo_timetag_now(&now); lo_timetag tt = lo_message_get_timestamp(m); if (memcmp(&tt, &LO_TT_IMMEDIATE, sizeof(lo_timetag))==0) fprintf(output_file, "%u %u %s %s ", now.sec, now.frac, path, types); else fprintf(output_file, "%u %u %s %s ", tt.sec, tt.frac, path, types); lo_arg **a = lo_message_get_argv(m); const char *t; int i=0; for (t=types; *t; t++, i++) { if (*t == 'i') fprintf(output_file, " %d", a[i]->i); else if (*t == 'f') fprintf(output_file, " %g", a[i]->f); else if (*t == 's') fprintf(output_file, " %s", &a[i]->s); } fprintf(output_file, "\n"); fflush(output_file); if (now.sec > last_write.sec) { printf("."); fflush(stdout); last_write = now; } }
/* catch any incoming messages and display them. returning 1 means that the * message has not been fully handled and the server should try other methods */ int remote_DNS::pingHandler(const char *path, const char *types, lo_arg ** argv, int argc, void *data, void *user_data) { remote_DNS* dns = (remote_DNS*)user_data; member messageSender; messageSender.pid = argv[0]->i; messageSender.hostname = (char *)argv[1]; lo_timetag_now(&messageSender.timetag); ostringstream convert; convert << messageSender.pid; string key = messageSender.hostname + ":" + convert.str(); if (dns->fLocker.Lock()) { // if (dns->fClients[key].timetag.sec == 0) // printf("remote_DNS::Connected HostName = %s\n", messageSender.hostname.c_str()); // printf("Client %s updated timetag %i\n", key.c_str(), messageSender.timetag.sec); dns->fClients[key] = messageSender; gDNS->fLocker.Unlock(); } return 0; }
void mapper_timetag_now(mapper_timetag_t *timetag) { lo_timetag_now((lo_timetag*)timetag); }
int main() { lo_blob btest = lo_blob_new(sizeof(testdata), testdata); lo_server_thread st, sta, stb; lo_server s = lo_server_new(NULL, error); lo_bundle b; lo_message m1, m2; char *server_url, *path, *protocol, *host, *port; const char *host2, *port2; lo_address a; uint8_t midi_data[4] = {0xff, 0xf7, 0xAA, 0x00}; union end_test32 et32; union end_test64 et64; lo_timetag tt = {0x1, 0x80000000}, sched; int count; int proto; char cmd[256]; test_deserialise(); sta = lo_server_thread_new("7591", error); stb = lo_server_thread_new("7591", rep_error); if (stb) { fprintf(stderr, "FAILED: create bad server thread object!\n"); exit(1); } lo_server_thread_free(sta); /* leak check */ st = lo_server_thread_new(NULL, error); lo_server_thread_start(st); #ifdef WIN32 Sleep(4); #else usleep(4000); #endif lo_server_thread_stop(st); lo_server_thread_free(st); st = lo_server_thread_new(NULL, error); lo_server_thread_start(st); lo_server_thread_stop(st); lo_server_thread_free(st); st = lo_server_thread_new(NULL, error); lo_server_thread_free(st); st = lo_server_thread_new(NULL, error); lo_server_thread_free(st); st = lo_server_thread_new(NULL, error); a = lo_address_new_from_url("osc://localhost/"); TEST(a != NULL); lo_address_free(a); a = lo_address_new_from_url("osc.://localhost/"); TEST(a == NULL); atexit(exitcheck); printf("type tests\n"); TEST(sizeof(float) == sizeof(int32_t)); TEST(sizeof(double) == sizeof(int64_t)); et32.i = 0x23242526U; et32.i = lo_htoo32(et32.i); if (et32.c[0] != 0x23 || et32.c[1] != 0x24 || et32.c[2] != 0x25 || et32.c[3] != 0x26) { fprintf(stderr, "failed 32bit endian conversion test\n"); fprintf(stderr, "0x23242526 -> %X\n", et32.i); exit(1); } else { printf("passed 32bit endian conversion test\n"); } et64.i = 0x232425262728292AULL; et64.i = lo_htoo64(et64.i); if (et64.c[0] != 0x23 || et64.c[1] != 0x24 || et64.c[2] != 0x25 || et64.c[3] != 0x26 || et64.c[4] != 0x27 || et64.c[5] != 0x28 || et64.c[6] != 0x29 || et64.c[7] != 0x2A) { fprintf(stderr, "failed 64bit endian conversion\n"); fprintf(stderr, "0x232425262728292A -> %llX\n", (long long unsigned int)et64.i); exit(1); } else { printf("passed 64bit endian conversion\n"); } printf("\n"); /* OSC URL tests */ path = lo_url_get_path("osc.udp://localhost:9999/a/path/is/here"); if (strcmp(path, "/a/path/is/here")) { printf("failed lo_url_get_path() test1\n"); printf("'%s' != '/a/path/is/here'\n", path); exit(1); } else { printf("passed lo_url_get_path() test1\n"); } free(path); protocol = lo_url_get_protocol("osc.udp://localhost:9999/a/path/is/here"); if (strcmp(protocol, "udp")) { printf("failed lo_url_get_protocol() test1\n"); printf("'%s' != 'udp'\n", protocol); exit(1); } else { printf("passed lo_url_get_protocol() test1\n"); } free(protocol); protocol = lo_url_get_protocol("osc.tcp://localhost:9999/a/path/is/here"); if (strcmp(protocol, "tcp")) { printf("failed lo_url_get_protocol() test2\n"); printf("'%s' != 'tcp'\n", protocol); exit(1); } else { printf("passed lo_url_get_protocol() test2\n"); } free(protocol); protocol = lo_url_get_protocol("osc.udp://[::ffff:localhost]:9999/a/path/is/here"); if (strcmp(protocol, "udp")) { printf("failed lo_url_get_protocol() test1 (IPv6)\n"); printf("'%s' != 'udp'\n", protocol); exit(1); } else { printf("passed lo_url_get_protocol() test1 (IPv6)\n"); } free(protocol); proto = lo_url_get_protocol_id("osc.udp://localhost:9999/a/path/is/here"); if (proto != LO_UDP) { printf("failed lo_url_get_protocol_id() test1\n"); printf("'%d' != LO_UDP\n", proto); exit(1); } else { printf("passed lo_url_get_protocol_id() test1\n"); } proto = lo_url_get_protocol_id("osc.tcp://localhost:9999/a/path/is/here"); if (proto != LO_TCP) { printf("failed lo_url_get_protocol_id() test2\n"); printf("'%d' != LO_TCP\n", proto); exit(1); } else { printf("passed lo_url_get_protocol_id() test2\n"); } proto = lo_url_get_protocol_id("osc.invalid://localhost:9999/a/path/is/here"); if (proto != -1) { printf("failed lo_url_get_protocol_id() test3\n"); printf("'%d' != -1\n", proto); exit(1); } else { printf("passed lo_url_get_protocol_id() test3\n"); } proto = lo_url_get_protocol_id("osc.udp://[::ffff:localhost]:9999/a/path/is/here"); if (proto != LO_UDP) { printf("failed lo_url_get_protocol_id() test1 (IPv6)\n"); printf("'%d' != LO_UDP\n", proto); exit(1); } else { printf("passed lo_url_get_protocol_id() test1 (IPv6)\n"); } host = lo_url_get_hostname("osc.udp://foo.example.com:9999/a/path/is/here"); if (strcmp(host, "foo.example.com")) { printf("failed lo_url_get_hostname() test1\n"); printf("'%s' != 'foo.example.com'\n", host); exit(1); } else { printf("passed lo_url_get_hostname() test1\n"); } free(host); host = lo_url_get_hostname("osc.udp://[0000::::0001]:9999/a/path/is/here"); if (strcmp(host, "0000::::0001")) { printf("failed lo_url_get_hostname() test2 (IPv6)\n"); printf("'%s' != '0000::::0001'\n", host); exit(1); } else { printf("passed lo_url_get_hostname() test2 (IPv6)\n"); } free(host); port = lo_url_get_port("osc.udp://localhost:9999/a/path/is/here"); if (strcmp(port, "9999")) { printf("failed lo_url_get_port() test1\n"); printf("'%s' != '9999'\n", port); exit(1); } else { printf("passed lo_url_get_port() test1\n"); } free(port); port = lo_url_get_port("osc.udp://[::ffff:127.0.0.1]:9999/a/path/is/here"); if (strcmp(port, "9999")) { printf("failed lo_url_get_port() test1 (IPv6)\n"); printf("'%s' != '9999'\n", port); exit(1); } else { printf("passed lo_url_get_port() test1 (IPv6)\n"); } free(port); printf("\n"); a = lo_address_new_from_url("osc.tcp://foo.example.com:9999/"); host2 = lo_address_get_hostname(a); if (strcmp(host2, "foo.example.com")) { printf("failed lo_address_get_hostname() test\n"); printf("'%s' != 'foo.example.com'\n", host2); exit(1); } else { printf("passed lo_address_get_hostname() test\n"); } port2 = lo_address_get_port(a); if (strcmp(port2, "9999")) { printf("failed lo_address_get_port() test\n"); printf("'%s' != '9999'\n", port2); exit(1); } else { printf("passed lo_address_get_port() test\n"); } proto = lo_address_get_protocol(a); if (proto != LO_TCP) { printf("failed lo_address_get_protocol() test\n"); printf("'%d' != '%d'\n", proto, LO_TCP); exit(1); } else { printf("passed lo_address_get_protocol() test\n"); } server_url = lo_address_get_url(a); if (strcmp(server_url, "osc.tcp://foo.example.com:9999/")) { printf("failed lo_address_get_url() test\n"); printf("'%s' != '%s'\n", server_url, "osc.tcp://foo.example.com:9999/"); exit(1); } else { printf("passed lo_address_get_url() test\n"); } free(server_url); lo_address_free( a ); printf("\n"); /* Test blod sizes */ if (lo_blob_datasize(btest) != 5 || lo_blobsize(btest) != 12) { printf("blob is %d (%d) bytes long, should be 5 (12)\n", lo_blob_datasize(btest), lo_blobsize(btest)); lo_arg_pp(LO_BLOB, btest); printf(" <- blob\n"); exit(1); } /* Server method handler tests */ server_url = lo_server_thread_get_url(st); a = lo_address_new_from_url(server_url); printf("Server URL: %s\n", server_url); free(server_url); /* add method that will match the path /foo/bar, with two numbers, coerced * to float and int */ lo_server_thread_add_method(st, "/foo/bar", "fi", foo_handler, lo_server_thread_get_server(st)); lo_server_thread_add_method(st, "/reply", "s", reply_handler, NULL); lo_server_thread_add_method(st, "/lotsofformats", "fisbmhtdSccTFNI", lots_handler, NULL); lo_server_thread_add_method(st, "/coerce", "dfhiSs", coerce_handler, NULL); lo_server_thread_add_method(st, "/bundle", NULL, bundle_handler, NULL); lo_server_thread_add_method(st, "/timestamp", NULL, timestamp_handler, NULL); lo_server_thread_add_method(st, "/jitter", "ti", jitter_handler, NULL); lo_server_thread_add_method(st, "/pattern/foo", NULL, pattern_handler, "foo"); lo_server_thread_add_method(st, "/pattern/bar", NULL, pattern_handler, "bar"); lo_server_thread_add_method(st, "/pattern/baz", NULL, pattern_handler, "baz"); lo_server_thread_add_method(st, "/subtest", "i", subtest_handler, st); lo_server_thread_add_method(st, "/subtest-reply", "i", subtest_reply_handler, NULL); /* add method that will match any path and args */ lo_server_thread_add_method(st, NULL, NULL, generic_handler, NULL); /* add method that will match the path /quit with no args */ lo_server_thread_add_method(st, "/quit", "", quit_handler, NULL); /* check that the thread restarts */ lo_server_thread_start(st); lo_server_thread_stop(st); lo_server_thread_start(st); if (lo_send(a, "/foo/bar", "ff", 0.12345678f, 23.0f) == -1) { printf("OSC error A %d: %s\n", lo_address_errno(a), lo_address_errstr(a)); exit(1); } if (lo_send(a, "/foo/bar", "ff", 0.12345678f, 23.0f) == -1) { printf("OSC error B %d: %s\n", lo_address_errno(a), lo_address_errstr(a)); exit(1); } test_validation(a); test_multicast(st); lo_send(a, "/", "i", 242); lo_send(a, "/pattern/", "i", 243); #ifndef _MSC_VER /* MS compiler refuses to compile this case */ lo_send(a, "/bar", "ff", 0.12345678f, 1.0/0.0); #endif lo_send(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123, "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym", 'X', 'Y'); lo_send(a, "/coerce", "fdihsS", 0.1f, 0.2, 123, 124LL, "aaa", "bbb"); lo_send(a, "/coerce", "ffffss", 0.1f, 0.2f, 123.0, 124.0, "aaa", "bbb"); lo_send(a, "/coerce", "ddddSS", 0.1, 0.2, 123.0, 124.0, "aaa", "bbb"); lo_send(a, "/a/b/c/d", "sfsff", "one", 0.12345678f, "three", -0.00000023001f, 1.0); lo_send(a, "/a/b/c/d", "b", btest); TEST(test_varargs(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123, "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym", 'X', 'Y', LO_ARGS_END) == 0); #ifdef __GNUC__ // Note: Lack of support for variable-argument macros in non-GCC compilers // does not allow us to test for these conditions. // too many args TEST(test_varargs(a, "/lotsofformats", "f", 0.12345678f, 123, "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym", 'X', 'Y', LO_ARGS_END) != 0); // too many types TEST(test_varargs(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123, "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.5, LO_ARGS_END) != 0); #endif // test lo_message_add m1 = lo_message_new(); TEST(lo_message_add(m1, "fisbmhtdSccTFNI", 0.12345678f, 123, "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym", 'X', 'Y') == 0); lo_send_message(a, "/lotsofformats", m1); lo_message_free(m1); lo_blob_free(btest); lo_send(a, "/pattern/*", "s", "a"); lo_send(a, "/pattern/ba[rz]", "s", "b"); server_url = lo_server_thread_get_url(st); sprintf(cmd, "." PATHDELIM "subtest %s &", server_url); if (system(cmd) != 0) { fprintf(stderr, "Cannot execute subtest command\n"); exit(1); } system(cmd); free(server_url); #ifdef WIN32 Sleep(2000); #else sleep(2); #endif TEST(reply_count == 3); TEST(pattern_count == 5); TEST(subtest_count == 2); TEST(subtest_reply_count == 22); printf("\n"); { lo_timetag t = {10,0xFFFFFFFC}; b = lo_bundle_new(t); } m1 = lo_message_new(); lo_message_add_string(m1, "abcdefghijklmnopqrstuvwxyz"); lo_message_add_string(m1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); lo_bundle_add_message(b, "/bundle", m1); lo_send_bundle(a, b); /* This should be safe for multiple copies of the same message. */ lo_bundle_free_messages(b); { lo_timetag t = {1,2}; b = lo_bundle_new(t); } m1 = lo_message_new(); lo_message_add_int32(m1, 23); lo_message_add_string(m1, "23"); lo_bundle_add_message(b, "/bundle", m1); m2 = lo_message_new(); lo_message_add_string(m2, "24"); lo_message_add_int32(m2, 24); lo_bundle_add_message(b, "/bundle", m2); lo_bundle_add_message(b, "/bundle", m1); /* lo_send_bundle(a, b); if (a->errnum) { printf("error %d: %s\n", a->errnum, a->errstr); exit(1); } */ TEST(lo_send_bundle(a, b) == 88); /* Test freeing out-of-order copies of messages in a bundle. */ lo_bundle_free_messages(b); { lo_timetag t = {10,0xFFFFFFFE}; b = lo_bundle_new(t); } m1 = lo_message_new(); lo_message_add_string(m1, "abcdefghijklmnopqrstuvwxyz"); lo_message_add_string(m1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); lo_bundle_add_message(b, "/bundle", m1); lo_send_bundle(a, b); lo_message_free(m1); lo_bundle_free(b); lo_timetag_now(&sched); sched.sec += 5; b = lo_bundle_new(sched); m1 = lo_message_new(); lo_message_add_string(m1, "future"); lo_message_add_string(m1, "time"); lo_message_add_string(m1, "test"); lo_bundle_add_message(b, "/bundle", m1); lo_send_bundle(a, b); lo_message_free(m1); lo_bundle_free(b); lo_send_timestamped(a, sched, "/bundle", "s", "lo_send_timestamped() test"); /* test bundle timestamp ends up in message struct (and doesn't end up in unbundled messages) */ lo_timetag_now(&sched); lo_send_timestamped(a, sched, "/timestamp", "it", 1, sched); lo_send(a, "/timestamp", "it", 0, sched); #define JITTER_ITS 25 /* jitter tests */ { lo_timetag stamps[JITTER_ITS]; lo_timetag now; int i; for (i=0; i<JITTER_ITS; i++) { lo_timetag_now(&now); stamps[i] = now; stamps[i].sec += 1; stamps[i].frac = rand(); lo_send_timestamped(a, stamps[i], "/jitter", "ti", stamps[i], i); } } #ifdef WIN32 Sleep(2000); #else sleep(2); #endif lo_address_free(a); TEST(lo_server_thread_events_pending(st)); while (lo_server_thread_events_pending(st)) { printf("pending events, wait...\n"); #ifdef WIN32 fflush(stdout); Sleep(1000); #else sleep(1); #endif } TEST(bundle_count == 7); printf("\n"); printf("bundle timing jitter results:\n" "max jitter = %fs\n" "avg jitter = %fs\n" "min jitter = %fs\n\n", jitter_max, jitter_total/(float)jitter_count, jitter_min); server_url = lo_server_get_url(s); lo_server_add_method(s, NULL, NULL, generic_handler, NULL); a = lo_address_new_from_url(server_url); TEST(lo_server_recv_noblock(s, 0) == 0); printf("Testing noblock API on %s\n", server_url); lo_send(a, "/non-block-test", "f", 23.0); count = 0; while (!lo_server_recv_noblock(s, 10) && count++ < 1000) { } if (count >= 1000) { printf("lo_server_recv_noblock() test failed\n"); exit(1); } /* Delete methods */ lo_server_thread_del_method(st, "/coerce", "dfhiSs"); lo_server_del_method(s, NULL, NULL); lo_address_free(a); lo_server_free(s); free(server_url); #ifndef WIN32 { /* UNIX domain tests */ lo_address ua; lo_server us; char *addr; unlink("/tmp/testlo.osc"); us = lo_server_new_with_proto("/tmp/testlo.osc", LO_UNIX, error); ua = lo_address_new_from_url("osc.unix:///tmp/testlo.osc"); TEST(lo_server_get_protocol(us) == LO_UNIX); TEST(lo_send(ua, "/unix", "f", 23.0) == 16); TEST(lo_server_recv(us) == 16); addr = lo_server_get_url(us); TEST(!strcmp("osc.unix:////tmp/testlo.osc", addr)); free(addr); lo_address_free(ua); ua = lo_address_new_with_proto(LO_UNIX, NULL, "/tmp/testlo.osc"); TEST(lo_send(ua, "/unix", "f", 23.0) == 16); TEST(lo_server_recv(us) == 16); lo_server_free(us); lo_address_free(ua); } #endif { /* TCP tests */ lo_address ta; lo_server ts; char *addr; ts = lo_server_new_with_proto(NULL, LO_TCP, error); addr = lo_server_get_url(ts); ta = lo_address_new_from_url(addr); if (lo_address_errno(ta)) { printf("err: %s\n", lo_address_errstr(ta)); exit(1); } TEST(lo_server_get_protocol(ts) == LO_TCP); TEST(lo_send(ta, "/tcp", "f", 23.0) == 16); TEST(lo_send(ta, "/tcp", "f", 23.0) == 16); TEST(lo_server_recv(ts) == 16); TEST(lo_server_recv(ts) == 16); free(addr); lo_server_free(ts); lo_address_free(ta); } server_url = lo_server_thread_get_url(st); a = lo_address_new_from_url(server_url); /* exit */ lo_send(a, "/quit", NULL); lo_address_free(a); while (!done) { #ifdef WIN32 Sleep(1); #else usleep(1000); #endif } lo_server_thread_free(st); free(server_url); return 0; }
void main_loop(void *data) { int i,j,n; int32_t fseq = 0; //verbose = 2; // get the local IP adress for the TUIO2 source attribute char hostname[64]; struct hostent *hp = NULL; struct in_addr *addr = NULL; gethostname(hostname, 64); hp = gethostbyname(hostname); if (hp==NULL) { sprintf(hostname, "%s.local", hostname); hp = gethostbyname(hostname); } if (hp!=NULL) { for (i = 0; hp->h_addr_list[i] != 0; ++i) { addr = (struct in_addr *)(hp->h_addr_list[i]); } } else { //generate a random internet address srand ( (unsigned int)time(NULL) ); int32_t r = rand(); addr = (struct in_addr*)&r; } while (running) { uint8_t tag_count = 0; bool updated = false; lo_bundle osc_bundle = lo_bundle_new(LO_TT_IMMEDIATE); nfc_target ant[MAX_TARGET_COUNT]; // List ISO14443A targets if (verbose>1) printf("polling for a ISO14443A (MIFARE) tag:\n"); nfc_modulation nm = { .nmt = NMT_ISO14443A, .nbr = NBR_106, }; lo_timetag frame_time; lo_timetag_now (&frame_time); for (int dev=0;dev<no_devices;dev++) { if (pnd[dev] == NULL) continue; if (!running) return; lo_message frm_message = lo_message_new(); lo_message_add_int32(frm_message, fseq); lo_message_add_timetag(frm_message, frame_time); lo_message_add_int32(frm_message, 0); // sensor dim if (device_count>1) sprintf(source_string, "NFOSC:%d",dev); lo_message_add_string(frm_message, source_string); // source name lo_bundle_add_message(osc_bundle, "/tuio2/frm", frm_message); fseq++; int szTargetFound = nfc_initiator_list_passive_targets (pnd[dev], nm, ant, MAX_TARGET_COUNT); if (szTargetFound<0) { if (no_devices==1) printf("NFC reader disconnected ...\n"); else printf("NFC reader #%d disconnected ...\n",dev); pnd[dev] = NULL; device_count--; if (device_count==0) { running=false; return; } continue; } else if (szTargetFound>0) { for (n = 0; n < szTargetFound; n++) { if (!running) return; bool added = false; nfosc_t found_tag; found_tag.type_id = MIFARE_OTHER; found_tag.device_id = dev; decode_hex(ant[n].nti.nai.abtUid,ant[n].nti.nai.szUidLen); strcpy(found_tag.uid_str,uid_str); if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x04) && (ant[n].nti.nai.btSak == 0x09)) { if (verbose>1) printf("NXP MIFARE Mini - UID: %s\n",uid_str); found_tag.type_id = MIFARE_MINI; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x04) && (ant[n].nti.nai.btSak == 0x08)) { if (verbose>1) printf("NXP MIFARE Classic 1K - UID: %s\n",uid_str); found_tag.type_id = MIFARE_CLASSIC_1K; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x02) && (ant[n].nti.nai.btSak == 0x18)) { if (verbose>1) printf("NXP MIFARE Classic 4K - UID: %s\n",uid_str); found_tag.type_id = MIFARE_CLASSIC_4K; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x02) && (ant[n].nti.nai.btSak == 0x38)) { if (verbose>1) printf("Nokia MIFARE Classic 4K - emulated - UID: %s\n",uid_str); found_tag.type_id = MIFARE_CLASSIC_4K; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x44) && (ant[n].nti.nai.btSak == 0x00)) { if (verbose>1) printf("NXP MIFARE Ultralight - UID: %s\n",uid_str); found_tag.type_id = MIFARE_ULTRALIGHT; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x03) && (ant[n].nti.nai.abtAtqa[1] == 0x44) && (ant[n].nti.nai.btSak == 0x20)) { if (verbose>1) printf("NXP MIFARE DESFire - UID: %s\n",uid_str); } else if ((ant[n].nti.nai.abtAtqa[0] == 0x03) && (ant[n].nti.nai.abtAtqa[1] == 0x04) && (ant[n].nti.nai.btSak == 0x28)) { if (verbose>1) printf("NXP JCOP31 - UID: %s\n",uid_str); } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x48) && (ant[n].nti.nai.btSak == 0x20)) { /* @todo handle ATS to be able to know which one it is */ if (verbose>1) printf("NXP JCOP31 or JCOP41 - UID: %s\n",uid_str); } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x04) && (ant[n].nti.nai.btSak == 0x28)) { if (verbose>1) printf("NXP JCOP41 - UID: %s\n",uid_str); } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x04) && (ant[n].nti.nai.btSak == 0x88)) { if (verbose>1) printf("Infineon MIFARE Classic 1K - UID: %s\n",uid_str); found_tag.type_id = MIFARE_CLASSIC_1K; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x02) && (ant[n].nti.nai.btSak == 0x98)) { if (verbose>1) printf("Gemplus MPCOS - UID: %s\n",uid_str); } else if ((ant[n].nti.nai.abtAtqa[0] == 0x0C) && (ant[n].nti.nai.abtAtqa[1] == 0x00)) { /* @note not sure if Jewel can be detected using this modulation */ if (verbose>1) printf("Innovision R&T Jewel - UID: %s\n",uid_str); } else { if (verbose>1) { printf("ATQA (SENS_RES): %s\n", decode_hex(ant[n].nti.nai.abtAtqa,2)); printf(" UID (NFCID%c): ",(ant[n].nti.nai.abtUid[0]==0x08?'3':'1')); printf("%s\n",decode_hex(ant[n].nti.nai.abtUid,ant[n].nti.nai.szUidLen)); printf(" SAK (SEL_RES): %s\n", decode_hex(&ant[n].nti.nai.btSak,1)); if (ant[n].nti.nai.szAtsLen) { printf(" ATS (ATR): %s\n",decode_hex(ant[n].nti.nai.abtAts,ant[n].nti.nai.szAtsLen)); } printf("\n"); } } int32_t symbol_id = max_symbol_id; int32_t i; for (i=0;i<max_symbol_id;i++) { if (strcmp(tag_database[i].uid_str,found_tag.uid_str)==0) { symbol_id = i; found_tag.symbol_id = symbol_id; break; } } if (symbol_id==max_symbol_id) { symbol_id = max_symbol_id; max_symbol_id++; found_tag.symbol_id = symbol_id; session_id++; found_tag.session_id = session_id; tag_database[symbol_id] = found_tag; tag_buffer[buffer_size] = found_tag; buffer_size++; if (verbose) printf("assigning ID %d to UID %s\n",found_tag.symbol_id,found_tag.uid_str); added = true; } else { int32_t b_pos = buffer_size; for (i=0;i<buffer_size;i++) { if ((strcmp(tag_buffer[i].uid_str,found_tag.uid_str)==0) && (tag_buffer[i].device_id==found_tag.device_id)) { found_tag.session_id = tag_buffer[i].session_id; b_pos=i; break; } } if (b_pos==buffer_size) { session_id++; found_tag.session_id = session_id; tag_buffer[buffer_size] = found_tag; buffer_size++; added=true; } } lo_message sym_message = lo_message_new(); lo_message_add_int32(sym_message, found_tag.session_id); lo_message_add_int32(sym_message, found_tag.type_id); lo_message_add_int32(sym_message, found_tag.symbol_id); switch (found_tag.type_id) { case MIFARE_ULTRALIGHT: lo_message_add_string(sym_message, "mifare/ul"); break; case MIFARE_CLASSIC_1K: lo_message_add_string(sym_message, "mifare/1k"); break; case MIFARE_CLASSIC_4K: lo_message_add_string(sym_message, "mifare/4k"); break; case MIFARE_MINI: lo_message_add_string(sym_message, "mifare/mini"); break; default: lo_message_add_string(sym_message, "mifare/other"); } lo_message_add_string(sym_message, found_tag.uid_str); lo_bundle_add_message(osc_bundle, "/tuio2/sym", sym_message); if (added) { lo_message add_message = lo_message_new(); lo_message_add_int32(add_message, found_tag.device_id); lo_message_add_int32(add_message, found_tag.symbol_id); lo_message_add_int32(add_message, found_tag.type_id); lo_message_add_string(add_message, found_tag.uid_str); lo_bundle_add_message(osc_bundle, "/nfosc/add", add_message); updated = true; if (verbose) printf("add %d %d %d %s\n",found_tag.device_id,found_tag.symbol_id,found_tag.type_id,found_tag.uid_str); } frame_buffer[tag_count] = found_tag; tag_count++; } } lo_message sid_message = lo_message_new(); for (i=0;i<tag_count;i++) if (frame_buffer[i].device_id==dev) lo_message_add_int32(sid_message, frame_buffer[i].session_id); lo_bundle_add_message(osc_bundle, "/tuio2/alv", sid_message); } for (i=0;i<buffer_size;i++) { bool removed = true; for (j=0;j<=tag_count;j++) { if ((strcmp(tag_buffer[i].uid_str,frame_buffer[j].uid_str)==0) && (tag_buffer[i].device_id == frame_buffer[j].device_id)) { removed=false; break; } } if (removed) { lo_message del_message = lo_message_new(); lo_message_add_int32(del_message, tag_buffer[i].device_id); lo_message_add_int32(del_message, tag_buffer[i].symbol_id); lo_message_add_int32(del_message, tag_buffer[i].type_id); lo_message_add_string(del_message, tag_buffer[i].uid_str); lo_bundle_add_message(osc_bundle, "/nfosc/del", del_message); updated = true; if (verbose) printf("del %d %d %d %s\n",tag_buffer[i].device_id,tag_buffer[i].symbol_id,tag_buffer[i].type_id,tag_buffer[i].uid_str); } } if (updated) { if(lo_send_bundle(target, osc_bundle) == -1) { fprintf(stderr, "an OSC error occured: %s\n", lo_address_errstr(target)); } } if (verbose>1) { if (tag_count==0) printf("no tag was found ...\n\n"); else if (tag_count==1) printf("1 tag was found ...\n\n"); else printf("%d tags were found ...\n\n",tag_count); } buffer_size = tag_count; for (i=0; i<tag_count; i++) { tag_buffer[i] = frame_buffer[i]; frame_buffer[i] = empty_tag; } for (int dev=0;dev<no_devices;dev++) { if (pnd[dev] == NULL) continue; if (nfc_device_set_property_bool(pnd[dev],NP_ACTIVATE_FIELD,false)<0) { if (running) { if (no_devices==1) printf("NFC reader disconnected ...\n"); else printf("NFC reader #%d disconnected ...\n",dev); } pnd[dev] = NULL; device_count--; if (device_count==0) { running=false; return; } } else { nfc_device_set_property_bool(pnd[dev],NP_ACTIVATE_FIELD,true); } } usleep(1000/no_devices); } }
void moNetOSCOut::SendDataMessage( int i, moDataMessage &datamessage ) { #ifdef OSCPACK if (packetStream==NULL) { cout << "moNetOSCOut::SendDataMessage > error: packetStream is NULL" << endl; return; } #endif //cout << "moNetOSCOut::SendDataMessage > start" << endl; #ifdef OSCPACK packetStream->Clear(); //cout << "moNetOSCOut::SendDataMessage > Clear() ok." << endl; (*packetStream) << osc::BeginBundleImmediate; //cout << "moNetOSCOut::SendDataMessage > BeginBundleImmediate ok." << endl; (*packetStream) << osc::BeginMessage( moText("")+ IntToStr(datamessage.Count()) ); //cout << "moNetOSCOut::SendDataMessage > data in messages:" << datamessage.Count() << endl; #else lo_timetag timetag; lo_timetag_now(&timetag); lo_bundle bundle = lo_bundle_new(timetag); lo_message ms = lo_message_new(); moText oscpath = ""; #endif moData data; int nfields = 0; int error = 0; try { for(int j=0; j< datamessage.Count(); j++) { data = datamessage[j]; if (debug_is_on) MODebug2->Message( moText("moNetOSCOut::SendDataMessage "+GetLabelName()+" > data:") + IntToStr(j) ); switch(data.Type()) { #ifdef OSCPACK case MO_DATA_NUMBER_FLOAT: (*packetStream) << data.Float(); break; case MO_DATA_NUMBER_INT: (*packetStream) << data.Int(); break; case MO_DATA_NUMBER_LONG: (*packetStream) << data.Long(); break; case MO_DATA_NUMBER_DOUBLE: (*packetStream) << data.Double(); break; case MO_DATA_TEXT: (*packetStream) << (char*)data.Text(); break; #else case MO_DATA_NUMBER_FLOAT: error = lo_message_add_float( ms , data.Float()); nfields++; break; case MO_DATA_NUMBER_INT: error = lo_message_add_int32( ms , data.Int()); nfields++; break; case MO_DATA_NUMBER_LONG: error = lo_message_add_int64( ms , data.Long()); nfields++; break; case MO_DATA_NUMBER_DOUBLE: error = lo_message_add_double( ms , data.Double()); nfields++; break; case MO_DATA_TEXT: if (oscpath=="") { oscpath = data.Text(); moText mot = data.Text().Left(50000); error = lo_message_add_string( ms , (char*)mot); nfields++; } else { moText mot = data.Text().Left(50000); error = lo_message_add_string( ms , (char*)mot); nfields++; } break; #endif } if (error<0) MODebug2->Error(moText("moNetOSCOut > data error adding value: ") + data.ToText() ); } #ifdef OSCPACK } catch(osc::Exception E) { MODebug2->Error( moText("moNetOSCOut > Exception: ") + E.what() + " packet actual size: (" + IntToStr( (*packetStream).Size() ) + ") " + " Data too long for buffer: (max OUTPUT_BUFFER_SIZE:" + IntToStr(OUTPUT_BUFFER_SIZE) + ") " + data.ToText() + " (size:"+ IntToStr(data.ToText().Length())+" )" + " (total size:" + IntToStr( data.ToText().Length() + (*packetStream).Size() ) + ")" ); } (*packetStream) << osc::EndMessage; //cout << "moNetOSCOut::SendDataMessage > osc::EndMessage ok" << endl; //cout << "osc::EndBundle: " << endl; //cout << osc::EndBundle << endl; #ifdef MO_WIN32 (*packetStream) << osc::EndBundle; #endif //cout << "moNetOSCOut::SendDataMessage > osc::EndBundle ok" << endl; //cout << "moNetOSCOut::SendDataMessage > sending." << endl; if (transmitSockets[i]) { //MODebug2->Message(moText("moNetOSCOut > sending ") + IntToStr(i) + " size:" + IntToStr(packetStream->Size()) ); transmitSockets[i]->Send( packetStream->Data(), packetStream->Size() ); } #else } catch(...) {
int lo_server_recv(lo_server s) { void *data; size_t size; char *path; char *types; double sched_time = lo_server_next_event_delay(s); #ifdef WIN32 fd_set ps; struct timeval stimeout; int res; #else struct pollfd ps; #endif again: if (sched_time > 0.01) { if (sched_time > 10.0) { sched_time = 10.0; } #ifdef WIN32 if(!initWSock()) return 0; ps.fd_count = 1; ps.fd_array[0] = s->socket; stimeout.tv_sec = sched_time; stimeout.tv_usec = (sched_time-stimeout.tv_sec)*1.e6; res = select(1,&ps,NULL,NULL,&stimeout); if(res == SOCKET_ERROR) { return 0; } if(!res) { sched_time = lo_server_next_event_delay(s); if (sched_time > 0.01) { goto again; } return dispatch_queued(s); } #else ps.fd = s->socket; ps.events = POLLIN | POLLPRI | POLLERR | POLLHUP; ps.revents = 0; poll(&ps, 1, (int)(sched_time * 1000.0)); if (ps.revents == POLLERR || ps.revents == POLLHUP) { return 0; } if (!ps.revents) { sched_time = lo_server_next_event_delay(s); if (sched_time > 0.01) { goto again; } return dispatch_queued(s); } #endif } else { return dispatch_queued(s); } if (s->protocol == LO_TCP) { data = lo_server_recv_raw_stream(s, &size); } else { data = lo_server_recv_raw(s, &size); } if (!data) { return 0; } path = data; types = data + lo_strsize(path); if (!strcmp(path, "#bundle")) { char *pos = types; uint32_t len; lo_timetag ts, now; lo_timetag_now(&now); ts.sec = lo_otoh32(*((uint32_t *)pos)); pos += 4; ts.frac = lo_otoh32(*((uint32_t *)pos)); pos += 4; while (pos - (char *)data < size) { len = lo_otoh32(*((uint32_t *)pos)); pos += 4; /* test for immedaite dispatch */ if ((ts.sec == 0 && ts.frac == 1) || lo_timetag_diff(ts, now) <= 0.0) { types = pos + lo_strsize(pos); dispatch_method(s, pos, types + 1, types + lo_strsize(types)); } else { queue_data(s, ts, pos, len); } pos += len; } free(data); return size; } else if (*types != ',') { lo_throw(s, LO_ENOTYPE, "Missing typetag", path); return -1; } dispatch_method(s, path, types+1, data); free(data); return size; }
int lo_server_dispatch_data(lo_server s, void *data, size_t size) { int result = 0; char *path = data; ssize_t len = lo_validate_string(data, size); if (len < 0) { lo_throw(s, -len, "Invalid message path", NULL); return len; } if (!strcmp(data, "#bundle")) { char *pos; int remain; uint32_t elem_len; lo_timetag ts, now; ssize_t bundle_result = lo_validate_bundle(data, size); if (bundle_result < 0) { lo_throw(s, -bundle_result, "Invalid bundle", NULL); return bundle_result; } pos = (char *)data + len; remain = size - len; lo_timetag_now(&now); ts.sec = lo_otoh32(*((uint32_t *)pos)); pos += 4; ts.frac = lo_otoh32(*((uint32_t *)pos)); pos += 4; remain -= 8; while (remain >= 4) { lo_message msg; elem_len = lo_otoh32(*((uint32_t *)pos)); pos += 4; remain -= 4; msg = lo_message_deserialise(pos, elem_len, &result); if (!msg) { lo_throw(s, result, "Invalid bundle element received", path); return -result; } // set timetag from bundle msg->ts = ts; // test for immediate dispatch if ((ts.sec == LO_TT_IMMEDIATE.sec && ts.frac == LO_TT_IMMEDIATE.frac) || lo_timetag_diff(ts, now) <= 0.0) { dispatch_method(s, pos, msg); lo_message_free(msg); } else { queue_data(s, ts, pos, msg); } pos += elem_len; remain -= elem_len; } } else { lo_message msg = lo_message_deserialise(data, size, &result); if (NULL == msg) { lo_throw(s, result, "Invalid message received", path); return -result; } dispatch_method(s, data, msg); lo_message_free(msg); } return size; }