// run OSC server in this thread but with an extra message handler // to allow the /plosc/stop message to terminate the loop. static int run_stoppable_server(my_server_thread s, int timeout) { lo_server_add_method(s->s, "/plosc/stop", NULL, stop_handler, (void *)s); my_server_thread_run(s,timeout); lo_server_del_method(s->s,"/plosc/stop",NULL); return TRUE; }
foreign_t del_handler(term_t server, term_t msg, term_t types) { my_server_thread s; char *pattern, *typespec; char buffer[256]; // !! space for up to 255 arguments int rc; rc = get_server(server,&s) && get_msg(msg,&pattern) && get_types(types,buffer,256,&typespec); if (rc) lo_server_del_method(s->s,pattern,typespec); return rc; }
void wxSpinTreeCtrl::connectToSpin() { // add our liblo callback to all listener sockets: spin::spinBaseContext *listener = spin::spinApp::Instance().getContext(); std::vector<lo_server>::iterator servIter; for (servIter = listener->lo_rxServs_.begin(); servIter != listener->lo_rxServs_.end(); ++servIter) { std::string oscPattern = std::string("/SPIN/" + spin::spinApp::Instance().getSceneID()); // remove existing callback (if exists): lo_server_del_method((*servIter), oscPattern.c_str(), NULL); // add new callback: lo_server_add_method((*servIter), oscPattern.c_str(), NULL, wxSpinTreeCtrl_liblo_callback, this); // TODO: we should really have callbacks for node messages and scene // messages rather than parsing every single message received //lo_server_add_method((*servIter), NULL, NULL, wxSpinTreeCtrl_liblo_callback, this); } }
void lo_server_thread_del_method(lo_server_thread st, const char *path, const char *typespec) { lo_server_del_method(st->s, path, typespec); }
static void unregister_osc_methods(char *prefix) { lo_server_thread srv = state.server; char *cmd_buf; ASPRINTF_OR_BAIL(&cmd_buf, "/%s/clear", prefix); lo_server_del_method(srv, cmd_buf, ""); lo_server_del_method(srv, cmd_buf, "i"); m_free(cmd_buf); ASPRINTF_OR_BAIL(&cmd_buf, "/%s/intensity", prefix); lo_server_del_method(srv, cmd_buf, ""); lo_server_del_method(srv, cmd_buf, "i"); m_free(cmd_buf); ASPRINTF_OR_BAIL(&cmd_buf, "/%s/led", prefix); lo_server_del_method(srv, cmd_buf, "iii"); m_free(cmd_buf); ASPRINTF_OR_BAIL(&cmd_buf, "/%s/led_row", prefix); lo_server_del_method(srv, cmd_buf, "ii"); lo_server_del_method(srv, cmd_buf, "iii"); m_free(cmd_buf); ASPRINTF_OR_BAIL(&cmd_buf, "/%s/led_col", prefix); lo_server_del_method(srv, cmd_buf, "ii"); lo_server_del_method(srv, cmd_buf, "iii"); m_free(cmd_buf); ASPRINTF_OR_BAIL(&cmd_buf, "/%s/frame", prefix); lo_server_del_method(srv, cmd_buf, "iiiiiiii"); lo_server_del_method(srv, cmd_buf, "iiiiiiiiii"); m_free(cmd_buf); }
void NonBlockOSCServer::removeMethod( const char* path, const char* types ) { lo_server_del_method( server, path, types ); }
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; }