Example #1
0
void osc_log_print( const char *msg, lo_message lomsg)
{
	int count = lo_message_get_argc( lomsg);
	int i;
	char *type = lo_message_get_types( lomsg);
	lo_arg** arg = lo_message_get_argv( lomsg);

	printf("%s ", msg);

	for( i = 0; i < count ; i++)
	{
		switch( type[i])
		{
			case 's': printf("s"); break;
			case 'i': printf("i"); break;
			case 'f': printf("f"); break;
			case 'l': printf("l"); break;
		}
	}

	printf(" ");

	for( i = 0; i < count ; i++)
	{
		switch( type[i])
		{
			case 's': printf("%s ", &arg[i]->s); break;
			case 'i': printf("%d ", arg[i]->i32); break;
			case 'f': printf("%f ", arg[i]->f); break;
			case 'l': printf("%lu ", arg[i]->i64); break;
		}
	}

	printf("\n");
}
Example #2
0
File: Mixer.C Project: imv/non
void
Mixer::reply_to_finger ( lo_message msg )
{    
    int argc = lo_message_get_argc( msg );
    lo_arg **argv = lo_message_get_argv( msg );

    if ( argc >= 4 )
    {
        const char *url = &argv[0]->s;
        const char *name = &argv[1]->s;
        const char *version = &argv[2]->s;
        const char *id = &argv[3]->s;

        MESSAGE( "Discovered NON peer %s (%s) @ %s with ID \"%s\"", name, version, url, id );
        MESSAGE( "Registering Signals" );

        lo_address to = lo_address_new_from_url( &argv[0]->s );
        
        osc_endpoint->send( to,
                            "/non/hello",
                            osc_endpoint->url(),
                            APP_NAME,
                            VERSION,
                            instance_name );
        
        mixer->osc_endpoint->hello( url );
    
        lo_address_free( to );
    }
}
Example #3
0
void live_beat_handler_t::messageHandler(const char *path, lo_message& msg)
{
//	pic::logmsg() << "live_osc_beat_msg::messageHandler";
	if(lo_message_get_argc(msg) >= 1  && lo_message_get_types(msg)[0]==LO_INT32)
	{
		lo_arg** args= lo_message_get_argv(msg);
		int beat = args[0]->i;
//		pic::logmsg() << "live_osc_beat_msg::messageHandler:" << beat;
		processBeat(beat);
	}
}
Example #4
0
void live_arm_handler_t::messageHandler(const char *path, lo_message& msg)
{
//	pic::logmsg() << "live_arm_handler_t::messageHandler";
	if(lo_message_get_argc(msg) >=2
			&& lo_message_get_types(msg)[0]==LO_INT32
			&& lo_message_get_types(msg)[1]==LO_INT32
			)
	{
		lo_arg** args= lo_message_get_argv(msg);
		int track = args[0]->i;
		int armed = args[1]->i;
//		pic::logmsg() << "live_arm_handler_t::messageHandler:" << track << "," << armed;
		processArm(track,(bool) armed);
	}
}
Example #5
0
void live_clip_info_handler_t::messageHandler(const char *path, lo_message& msg)
{
//	pic::logmsg() << "live_osc_clip_info_msg::messageHandler";
	if(lo_message_get_argc(msg) >= 3
			&& lo_message_get_types(msg)[0]==LO_INT32
			&& lo_message_get_types(msg)[1]==LO_INT32
			&& lo_message_get_types(msg)[2]==LO_INT32)
	{
		lo_arg** args= lo_message_get_argv(msg);
		int track = args[0]->i;
		int clip = args[1]->i;
		int state = args[2]->i;
//		pic::logmsg() << "live_osc_clip_info_msg::messageHandler track :" << track << "clip" << clip << "state" << state;
		processClip(track,clip,(state_t) state);
	}
}
Example #6
0
static unsigned char parse_msg(void)
{
  int result = 0;
  int bytes_available = uip_datalen();

  unsigned char* pData = uip_appdata;

  result = 1;

  lo_message message = lo_message_deserialise(pData, bytes_available, &result);

  if (result == 0) {
    //char* path = lo_url_get_path(lo_address_get_url(lo_message_get_source(message)));
    lo_arg** argv = lo_message_get_argv(message);

    //if (!strcmp(path,'/set/rgb')) {
      lo_arg* red = argv[0];
      lo_arg* green = argv[1];
      lo_arg* blue = argv[2];

      float fRed = red->f;
      float fGreen = green->f;
      float fBlue = blue->f;

      analogWrite(redPin, (unsigned char)(fRed * 0xFF));
      analogWrite(greenPin, (unsigned char)(fGreen * 0xFF));
      analogWrite(bluePin, (unsigned char)(fBlue * 0xFF));
    /*}
    else if (!strcmp(path, '/set/hsi')) {
      lo_arg* H = argv[0];
      lo_arg* S = argv[1];
      lo_arg* I = argv[2];

      unsigned char rgb[3];
      hsi2rgb(H, S, I, rgb);

      analogWrite(redPin, rgb[0]);
      analogWrite(greenPin, rgb[1]);
      analogWrite(bluePin, rgb[2]);
    }*/

  }

  lo_message_free(message);
  s.state = STATE_QUIT;
  return 1;
}
// *****************************************************************************
void ReferencedStateSet::debug()
{
	lo_arg **args;
	int argc;
	char *argTypes;

	std::cout << "****************************************" << std::endl;
	std::cout << "************* STATE DEBUG: *************" << std::endl;

	std::cout << "\nReferencedStateSet: " << id->s_name << ", type: " << classType << std::endl;

	
	std::cout << "   Shared by:";
	for (unsigned i = 0; i < getNumParents(); i++)
		std::cout << " " << getParent(i)->getName();
	std::cout << std::endl;

	//osg::ref_ptr<ReferencedStateSet> test = this;
	//std::cout << "ref_count=" << test->getReferenceCount() << std::endl;
	
	
	vector<lo_message> nodeState = this->getState();
	vector<lo_message>::iterator nodeStateIterator;
	for (nodeStateIterator = nodeState.begin(); nodeStateIterator != nodeState.end(); ++nodeStateIterator)
	{
	    argTypes = lo_message_get_types(*nodeStateIterator);
	    argc = lo_message_get_argc(*nodeStateIterator);
	    args = lo_message_get_argv(*nodeStateIterator);

	    std::cout << "  ";
	    for (int i = 0; i < argc; i++) {
		    std::cout << " ";
	    	if (lo_is_numerical_type((lo_type)argTypes[i]))
	    	{
	    		std::cout << (float) lo_hires_val( (lo_type)argTypes[i], args[i] );
	    	} else if (strlen((char*) args[i])) {
	    		std::cout << (char*) args[i];
	    	} else {
	    		std::cout << "NULL";
	    	}
	    }
	    std::cout << std::endl;
	}
	
	BROADCAST(this, "s", "debug");
}
Example #8
0
void live_name_clip_handler_t::messageHandler(const char *path, lo_message& msg)
{
//	pic::logmsg() << "live_clip_name_handler_t::messageHandler";
	if(lo_message_get_argc(msg) >= 4
			&& lo_message_get_types(msg)[0]==LO_INT32
			&& lo_message_get_types(msg)[1]==LO_INT32
			&& lo_message_get_types(msg)[2]==LO_STRING
			&& lo_message_get_types(msg)[3]==LO_INT32)
	{
		lo_arg** args= lo_message_get_argv(msg);
		int track = args[0]->i;
		int clip = args[1]->i;
		std::string name=&args[2]->s;
		int  colour= args[3]->i;
//		pic::logmsg() << "live_name_clip_handler_t::messageHandler track :" << track << "clip" << clip << "name" << name;
		processClip(track,clip,name,colour);
	}
}
Example #9
0
File: Osc.cpp Project: EQ4/MRP
void OscTransmitter::sendMessage(const char * path, const char * type, const lo_message& message)
{
    if(debugMessages_) {
        cout << path << " " << type << " ";

        int argc = lo_message_get_argc(message);
        lo_arg **argv = lo_message_get_argv(message);
        for (int i=0; i<argc; i++) {
            lo_arg_pp((lo_type)type[i], argv[i]);
            cout << " ";
        }
        cout << endl;
    }
    
	// Send message to everyone who's currently listening
	for(vector<lo_address>::iterator it = addresses_.begin(); it != addresses_.end(); it++) {
		lo_send_message(*it, path, message);
	}
}
Example #10
0
void live_track_info_handler_t::messageHandler(const char *path, lo_message& msg)
{
//	pic::logmsg() << "live_track_info_handler_t::messageHandler";
	if(lo_message_get_argc(msg) >= 5
			&& lo_message_get_types(msg)[0]==LO_INT32
			&& lo_message_get_types(msg)[1]==LO_INT32
			&& lo_message_get_types(msg)[2]==LO_INT32
			&& lo_message_get_types(msg)[3]==LO_INT32
			&& lo_message_get_types(msg)[4]==LO_FLOAT
			)
	{
		lo_arg** args= lo_message_get_argv(msg);
		int track = args[0]->i;
		int armed = args[1]->i;
		int clip = args[2]->i;
		int state = args[3]->i;
		float length = args[4]->i;
		processClip(track,(bool) armed,clip, (state_t) state,length);
	}
}
Example #11
0
/* 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;
    }
}
Example #12
0
void test_deserialise()
{
    char *buf, *buf2, *tmp;
    const char *types = NULL, *path;
    lo_arg **argv = NULL;
    size_t len, size;
    char data[256];
    int result = 0;

    lo_blob btest = lo_blob_new(sizeof(testdata), testdata);
    uint8_t midi_data[4] = {0xff, 0xf7, 0xAA, 0x00};
    lo_timetag tt = {0x1, 0x80000000};
    lo_blob b = NULL;

    // build a message
    lo_message msg = lo_message_new();
    TEST(0 == lo_message_get_argc(msg));
    lo_message_add_float(msg, 0.12345678f);             // 0  f
    lo_message_add_int32(msg, 123);                     // 1  i
    lo_message_add_string(msg, "123");                  // 2  s
    lo_message_add_blob(msg, btest);                    // 3  b
    lo_message_add_midi(msg, midi_data);                // 4  m
    lo_message_add_int64(msg, 0x0123456789abcdefULL);   // 5  h
    lo_message_add_timetag(msg, tt);                    // 6  t
    lo_message_add_double(msg, 0.9999);                 // 7  d
    lo_message_add_symbol(msg, "sym");                  // 8  S
    lo_message_add_char(msg, 'X');                      // 9  c
    lo_message_add_char(msg, 'Y');                      // 10 c
    lo_message_add_true(msg);                           // 11 T
    lo_message_add_false(msg);                          // 12 F
    lo_message_add_nil(msg);                            // 13 N
    lo_message_add_infinitum(msg);                      // 14 I

    // test types, args
    TEST(15 == lo_message_get_argc(msg));
    types = lo_message_get_types(msg);
    TEST(NULL != types);
    argv = lo_message_get_argv(msg);
    TEST(NULL != argv);
    TEST('f' == types[0] && fabs(argv[0]->f - 0.12345678f) < FLT_EPSILON);
    TEST('i' == types[1] && 123 == argv[1]->i);
    TEST('s' == types[2] && !strcmp(&argv[2]->s, "123"));
    TEST('b' == types[3]);
    b = (lo_blob)argv[3];
    TEST(lo_blob_datasize(b) == sizeof(testdata));
    TEST(12 == lo_blobsize(b));
    TEST(!memcmp(lo_blob_dataptr(b), &testdata, sizeof(testdata)));
    TEST('m' == types[4]  && !memcmp(&argv[4]->m, midi_data, 4));
    TEST('h' == types[5]  && 0x0123456789abcdefULL == argv[5]->h);
    TEST('t' == types[6]  && 1 == argv[6]->t.sec && 0x80000000 == argv[6]->t.frac);
    TEST('d' == types[7]  && fabs(argv[7]->d - 0.9999) < FLT_EPSILON);
    TEST('S' == types[8]  && !strcmp(&argv[8]->s, "sym"));
    TEST('c' == types[9]  && 'X' == argv[9]->c);
    TEST('c' == types[10] && 'Y' == argv[10]->c);
    TEST('T' == types[11] && NULL == argv[11]);
    TEST('F' == types[12] && NULL == argv[12]);
    TEST('N' == types[13] && NULL == argv[13]);
    TEST('I' == types[14] && NULL == argv[14]);

    // serialise it
    len = lo_message_length(msg, "/foo");
    printf("serialise message_length=%d\n", (int)len);
    buf = calloc(len, sizeof(char));
    size = 0;
    tmp = lo_message_serialise(msg, "/foo", buf, &size);
    TEST(tmp == buf && size == len && 92 == len);
    lo_message_free(msg);

    // deserialise it
    printf("deserialise\n");
    path = lo_get_path(buf, len);
    TEST(NULL != path && !strcmp(path, "/foo"));
    msg = lo_message_deserialise(buf, size, NULL);
    TEST(NULL != msg);

    // repeat same test as above
    TEST(15 == lo_message_get_argc(msg));
    types = lo_message_get_types(msg);
    TEST(NULL != types);
    argv = lo_message_get_argv(msg);
    TEST(NULL != argv);
    TEST('f' == types[0] && fabs(argv[0]->f - 0.12345678f) < FLT_EPSILON);
    TEST('i' == types[1] && 123 == argv[1]->i);
    TEST('s' == types[2] && !strcmp(&argv[2]->s, "123"));
    TEST('b' == types[3]);
    b = (lo_blob)argv[3];
    TEST(lo_blob_datasize(b) == sizeof(testdata));
    TEST(12 == lo_blobsize(b));
    TEST(!memcmp(lo_blob_dataptr(b), &testdata, sizeof(testdata)));
    TEST('m' == types[4]  && !memcmp(&argv[4]->m, midi_data, 4));
    TEST('h' == types[5]  && 0x0123456789abcdefULL == argv[5]->h);
    TEST('t' == types[6]  && 1 == argv[6]->t.sec && 0x80000000 == argv[6]->t.frac);
    TEST('d' == types[7]  && fabs(argv[7]->d - 0.9999) < FLT_EPSILON);
    TEST('S' == types[8]  && !strcmp(&argv[8]->s, "sym"));
    TEST('c' == types[9]  && 'X' == argv[9]->c);
    TEST('c' == types[10] && 'Y' == argv[10]->c);
    TEST('T' == types[11] && NULL == argv[11]);
    TEST('F' == types[12] && NULL == argv[12]);
    TEST('N' == types[13] && NULL == argv[13]);
    TEST('I' == types[14] && NULL == argv[14]);

    // serialise it again, compare
    len = lo_message_length(msg, "/foo");
    printf("serialise message_length=%d\n", (int)len);
    buf2 = calloc(len, sizeof(char));
    size = 0;
    tmp = lo_message_serialise(msg, "/foo", buf2, &size);
    TEST(tmp == buf2 && size == len && 92 == len);
    TEST(!memcmp(buf, buf2, len));
    lo_message_free(msg);

    lo_blob_free(btest);
    free(buf);
    free(buf2);

    // deserialise failure tests with invalid message data

    msg = lo_message_deserialise(data, 0, &result); // 0 size
    TEST(NULL == msg && LO_ESIZE == result);

    snprintf(data, 256, "%s", "/foo"); // unterminated path string
    msg = lo_message_deserialise(data, 4, &result);
    TEST(NULL == msg && LO_EINVALIDPATH == result);

    snprintf(data, 256, "%s", "/f_o"); // non-0 in pad area
    msg = lo_message_deserialise(data, 4, &result);
    TEST(NULL == msg && LO_EINVALIDPATH == result);

    snprintf(data, 256, "%s", "/t__"); // types missing
    replace_char(data, 4, '_', '\0');
    msg = lo_message_deserialise(data, 4, &result);
    TEST(NULL == msg && LO_ENOTYPE == result);

    snprintf(data, 256, "%s%s", "/t__", "____"); // types empty
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 8, &result);
    TEST(NULL == msg && LO_EBADTYPE == result);

    snprintf(data, 256, "%s%s", "/t__", ",f_"); // short message
    replace_char(data, 7, '_', '\0');
    msg = lo_message_deserialise(data, 7, &result);
    TEST(NULL == msg && LO_EINVALIDTYPE == result);

    snprintf(data, 256, "%s%s", "/t__", "ifi_"); // types missing comma
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 8, &result);
    TEST(NULL == msg && LO_EBADTYPE == result);

    snprintf(data, 256, "%s%s", "/t__", ",ifi"); // types unterminated
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 8, &result);
    TEST(NULL == msg && LO_EINVALIDTYPE == result);

    snprintf(data, 256, "%s%s", "/t__", ",ii_"); // not enough arg data
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 12, &result);
    TEST(NULL == msg && LO_EINVALIDARG == result);

    snprintf(data, 256, "%s%s", "/t__", ",ii_"); // not enough arg data again
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 15, &result);
    TEST(NULL == msg && LO_EINVALIDARG == result);

    snprintf(data, 256, "%s%s", "/t__", ",f__"); // too much arg data
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 16, &result);
    TEST(NULL == msg && LO_ESIZE == result);

    snprintf(data, 256, "%s%s", "/t__", ",bs_"); // blob longer than msg length
    replace_char(data, 8, '_', '\0');
    *(uint32_t *)(data + 8) = lo_htoo32((uint32_t)99999);
    msg = lo_message_deserialise(data, 256, &result);
    TEST(NULL == msg && LO_EINVALIDARG == result);
}
Example #13
0
int main(int argc, char **argv)
{
    int i, j, result = 0;

    // process flags for -v verbose, -h help
    for (i = 1; i < argc; i++) {
        if (argv[i] && argv[i][0] == '-') {
            int len = strlen(argv[i]);
            for (j = 1; j < len; j++) {
                switch (argv[i][j]) {
                    case 'h':
                        eprintf("testdatabase.c: possible arguments "
                                "-q quiet (suppress output), "
                                "-h help\n");
                        return 1;
                        break;
                    case 'q':
                        verbose = 0;
                        break;
                    default:
                        break;
                }
            }
        }
    }

    lo_message lom;
    mapper_message msg;
    uint64_t id = 1;
    mapper_network net = mapper_network_new(0, 0, 0);
    mapper_database db = &net->database;

    mapper_device dev, *pdev, *pdev2;
    mapper_signal sig, *psig, *psig2;
    mapper_map *pmap, *pmap2;

    /* Test the database functions */

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }
    lo_message_add_string(lom, "@port");
    lo_message_add_int32(lom, 1234);
    lo_message_add_string(lom, "@host");
    lo_message_add_string(lom, "localhost");
    lo_message_add_string(lom, "@num_inputs");
    lo_message_add_int32(lom, 2);
    lo_message_add_string(lom, "@num_outputs");
    lo_message_add_int32(lom, 2);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_device(db, "testdatabase.1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }
    lo_message_add_string(lom, "@port");
    lo_message_add_int32(lom, 1234);
    lo_message_add_string(lom, "@host");
    lo_message_add_string(lom, "localhost");
    lo_message_add_string(lom, "@num_inputs");
    lo_message_add_int32(lom, 2);
    lo_message_add_string(lom, "@num_outputs");
    lo_message_add_int32(lom, 1);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_device(db, "testdatabase__.2", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }
    lo_message_add_string(lom, "@port");
    lo_message_add_int32(lom, 3000);
    lo_message_add_string(lom, "@host");
    lo_message_add_string(lom, "192.168.0.100");

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_device(db, "testdatabase.3", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }
    lo_message_add_string(lom, "@port");
    lo_message_add_int32(lom, 5678);
    lo_message_add_string(lom, "@host");
    lo_message_add_string(lom, "192.168.0.100");

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_device(db, "testdatabase__.4", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }
    lo_message_add_string(lom, "@direction");
    lo_message_add_string(lom, "input");
    lo_message_add_string(lom, "@type");
    lo_message_add_char(lom, 'f');
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_signal(db, "in1", "testdatabase.1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@direction");
    lo_message_add_string(lom, "input");
    lo_message_add_string(lom, "@type");
    lo_message_add_char(lom, 'f');
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_signal(db, "in2", "testdatabase.1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@direction");
    lo_message_add_string(lom, "output");
    lo_message_add_string(lom, "@type");
    lo_message_add_char(lom, 'f');
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_signal(db, "out1", "testdatabase.1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@direction");
    lo_message_add_string(lom, "output");
    lo_message_add_string(lom, "@type");
    lo_message_add_char(lom, 'f');
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_signal(db, "out2", "testdatabase.1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@direction");
    lo_message_add_string(lom, "output");
    lo_message_add_string(lom, "@type");
    lo_message_add_char(lom, 'f');
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_signal(db, "out1", "testdatabase__.2", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@mode");
    lo_message_add_string(lom, "bypass");
    lo_message_add_string(lom, "@dst@bound_min");
    lo_message_add_string(lom, "none");
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    const char *src_sig_name = "testdatabase.1/out2";
    mapper_database_add_or_update_map(db, 1, &src_sig_name,
                                      "testdatabase__.2/in1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@mode");
    lo_message_add_string(lom, "bypass");
    lo_message_add_string(lom, "@dst@bound_min");
    lo_message_add_string(lom, "none");
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    src_sig_name = "testdatabase__.2/out1";
    mapper_database_add_or_update_map(db, 1, &src_sig_name,
                                      "testdatabase.1/in1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@mode");
    lo_message_add_string(lom, "expression");
    lo_message_add_string(lom, "@expression");
    lo_message_add_string(lom, "(x-10)*80");
    lo_message_add_string(lom, "@dst@bound_min");
    lo_message_add_string(lom, "clamp");
    lo_message_add_string(lom, "@src@min");
    lo_message_add_float(lom, 0.f);
    lo_message_add_float(lom, 1.f);
    lo_message_add_string(lom, "@src@max");
    lo_message_add_float(lom, 1.f);
    lo_message_add_float(lom, 2.f);
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    src_sig_name = "testdatabase.1/out1";
    mapper_database_add_or_update_map(db, 1, &src_sig_name,
                                      "testdatabase__.2/in2", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@mode");
    lo_message_add_string(lom, "expression");
    lo_message_add_string(lom, "@expression");
    lo_message_add_string(lom, "(x-10)*80");
    lo_message_add_string(lom, "@dst@bound_min");
    lo_message_add_string(lom, "clamp");
    lo_message_add_string(lom, "@src@min");
    lo_message_add_float(lom, 0.f);
    lo_message_add_float(lom, 1.f);
    lo_message_add_string(lom, "@src@max");
    lo_message_add_float(lom, 1.f);
    lo_message_add_float(lom, 2.f);
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    src_sig_name = "testdatabase.1/out1";
    mapper_database_add_or_update_map(db, 1, &src_sig_name,
                                      "testdatabase__.2/in1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    /*********/

    if (verbose) {
        eprintf("Dump:\n");
        mapper_database_print(db);
    }

    /*********/

    eprintf("\n--- Devices ---\n");

    eprintf("\nWalk the whole database:\n");
    pdev = mapper_database_devices(db);
    int count=0;
    if (!pdev) {
        eprintf("mapper_database_devices() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices() returned something "
               "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 4) {
        eprintf("Expected 4 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind device named 'testdatabase.3':\n");

    dev = mapper_database_device_by_name(db, "testdatabase.3");
    if (!dev) {
        eprintf("Not found.\n");
        result = 1;
        goto done;
    }

    printdevice(dev);

    /*********/

    eprintf("\nFind device named 'dummy':\n");

    dev = mapper_database_device_by_name(db, "dummy");
    if (dev) {
        eprintf("unexpected found 'dummy': %p\n", dev);
        result = 1;
        goto done;
    }
    eprintf("  not found, good.\n");

    /*********/

    eprintf("\nFind devices matching '__':\n");

    pdev = mapper_database_devices_by_name(db, "*__*");

    count=0;
    if (!pdev) {
        eprintf("mapper_database_devices_by_name() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices_by_name() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind devices with property 'host'=='192.168.0.100':\n");

    pdev = mapper_database_devices_by_property(db, "host", 1, 's',
                                               "192.168.0.100", MAPPER_OP_EQUAL);

    count=0;
    if (!pdev) {
        eprintf("mapper_database_devices_by_property() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices_by_property() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind devices with property 'port'<5678:\n");

    int port = 5678;
    pdev = mapper_database_devices_by_property(db, "port", 1, 'i', &port,
                                               MAPPER_OP_LESS_THAN);

    count=0;
    if (!pdev) {
        eprintf("mapper_database_devices_by_property() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices_by_property() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 3) {
        eprintf("Expected 3 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind devices with property 'num_outputs'==2:\n");
    int temp = 2;
    pdev = mapper_database_devices_by_property(db, "num_outputs", 1, 'i', &temp,
                                               MAPPER_OP_EQUAL);

    count=0;
    if (!pdev) {
        eprintf("mapper_database_devices_by_property() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices_by_property() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 1) {
        eprintf("Expected 1 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind devices with properties 'host'!='localhost' AND 'port'>=4000:\n");

    pdev = mapper_database_devices_by_property(db, "host", 1, 's', "localhost",
                                               MAPPER_OP_NOT_EQUAL);
    pdev2 = mapper_database_devices_by_property(db, "port", 1, 'i', &port,
                                                MAPPER_OP_GREATER_THAN_OR_EQUAL);
    pdev = mapper_device_query_intersection(pdev, pdev2);

    count=0;
    if (!pdev) {
        eprintf("mapper_database_devices_by_property() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices_by_property() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 1) {
        eprintf("Expected 1 record, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\n--- Signals ---\n");

    eprintf("\nFind all signals for device 'testdatabase.1':\n");

    dev = mapper_database_device_by_name(db, "testdatabase.1");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);

    count=0;
    if (!psig) {
        eprintf("mapper_device_signals() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*psig) {
        eprintf("mapper_device_signals() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (psig) {
        count ++;
        printsignal(*psig);
        psig = mapper_signal_query_next(psig);
    }

    if (count != 4) {
        eprintf("Expected 4 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind all signals for device 'testdatabase__xx.2':\n");

    dev = mapper_database_device_by_name(db, "testdatabase__xx.2");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);

    count=0;
    if (psig) {
        eprintf("mapper_device_signals() incorrectly found something.\n");
        printsignal(*psig);
        mapper_signal_query_done(psig);
        result = 1;
        goto done;
    }
    else
        eprintf("  correctly returned 0.\n");

    /*********/

    eprintf("\nFind all outputs for device 'testdatabase__.2':\n");

    dev = mapper_database_device_by_name(db, "testdatabase__.2");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);

    count=0;
    if (!psig) {
        eprintf("mapper_device_signals() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*psig) {
        eprintf("mapper_device_signals() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (psig) {
        count ++;
        printsignal(*psig);
        psig = mapper_signal_query_next(psig);
    }

    if (count != 3) {
        eprintf("Expected 3 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind signal matching 'in' for device 'testdatabase.1':\n");

    dev = mapper_database_device_by_name(db, "testdatabase.1");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);
    psig2 = mapper_database_signals_by_name(db, "*in*");
    psig = mapper_signal_query_intersection(psig, psig2);

    count=0;
    if (!psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (psig) {
        count ++;
        printsignal(*psig);
        psig = mapper_signal_query_next(psig);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind signal matching 'out' for device 'testdatabase.1':\n");

    dev = mapper_database_device_by_name(db, "testdatabase.1");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);
    psig2 = mapper_database_signals_by_name(db, "*out*");
    psig = mapper_signal_query_intersection(psig, psig2);

    count=0;
    if (!psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (psig) {
        count ++;
        printsignal(*psig);
        psig = mapper_signal_query_next(psig);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind signal matching 'out' for device 'testdatabase__.2':\n");

    dev = mapper_database_device_by_name(db, "testdatabase__.2");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);
    psig2 = mapper_database_signals_by_name(db, "*out*");
    psig = mapper_signal_query_intersection(psig, psig2);

    count=0;
    if (!psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (psig) {
        count ++;
        printsignal(*psig);
        psig = mapper_signal_query_next(psig);
    }

    if (count != 1) {
        eprintf("Expected 1 record, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\n--- maps ---\n");

    eprintf("\nFind maps with source 'out1':\n");

    psig = mapper_database_signals_by_name(db, "out1");
    pmap = 0;
    while (psig) {
        pmap2 = mapper_signal_maps(*psig, MAPPER_DIR_OUTGOING);
        pmap = mapper_map_query_union(pmap, pmap2);
        psig = mapper_signal_query_next(psig);
    }

    count=0;
    if (!pmap) {
        eprintf("combined query returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("combined query returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 3) {
        eprintf("Expected 3 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind maps for device 'testdatabase.1', source 'out1':\n");

    dev = mapper_database_device_by_name(db, "testdatabase.1");
    sig = mapper_device_signal_by_name(dev, "out1");
    pmap = mapper_signal_maps(sig, 0);

    count=0;
    if (!pmap) {
        eprintf("mapper_signal_maps() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("mapper_signal_maps() returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind maps with destination signal named 'in2':\n");

    psig = mapper_database_signals_by_name(db, "in2");
    pmap = 0;
    while (psig) {
        pmap2 = mapper_signal_maps(*psig, MAPPER_DIR_INCOMING);
        pmap = mapper_map_query_union(pmap, pmap2);
        psig = mapper_signal_query_next(psig);
    }

    count=0;
    if (!pmap) {
        eprintf("combined query returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("combined query returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 1) {
        eprintf("Expected 1 record, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind maps for device 'testdatabase__.2', destination 'in1':\n");

    dev = mapper_database_device_by_name(db, "testdatabase__.2");
    sig = mapper_device_signal_by_name(dev, "in1");
    pmap = mapper_signal_maps(sig, MAPPER_DIR_INCOMING);

    count=0;
    if (!pmap) {
        eprintf("mapper_signal_maps() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("mapper_signal_maps() returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind maps for source device 'testdatabase__.2', signal 'out1'"
            "\n          AND dest device 'testdatabase.1', signal 'in1':\n");

    // get maps with source signal
    dev = mapper_database_device_by_name(db, "testdatabase__.2");
    sig = mapper_device_signal_by_name(dev, "out1");
    pmap = mapper_signal_maps(sig, MAPPER_DIR_OUTGOING);

    // get maps with destination signal
    dev = mapper_database_device_by_name(db, "testdatabase.1");
    sig = mapper_device_signal_by_name(dev, "in1");
    pmap2 = mapper_signal_maps(sig, MAPPER_DIR_INCOMING);

    // intersect map queries
    pmap = mapper_map_query_intersection(pmap, pmap2);

    count=0;
    if (!pmap) {
        eprintf("combined query returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("combined query returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 1) {
        eprintf("Expected 1 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind maps for source device 'testdatabase__.2', signals matching 'out',"
            "\n          AND dest device 'testdatabase.1', all signals:\n");

    // build source query
    dev = mapper_database_device_by_name(db, "testdatabase__.2");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);
    psig2 = mapper_database_signals_by_name(db, "*out*");
    psig = mapper_signal_query_intersection(psig, psig2);

    pmap = 0;
    while (psig) {
        pmap2 = mapper_signal_maps(*psig, MAPPER_DIR_OUTGOING);
        pmap = mapper_map_query_union(pmap, pmap2);
        psig = mapper_signal_query_next(psig);
    }

    // build destination query
    dev = mapper_database_device_by_name(db, "testdatabase.1");
    pmap2 = mapper_device_maps(dev, MAPPER_DIR_ANY);

    // intersect queries
    pmap = mapper_map_query_intersection(pmap, pmap2);

    count=0;
    if (!pmap) {
        eprintf("combined query returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("combined query returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 1) {
        eprintf("Expected 1 record, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/
done:
    mapper_network_free(net);
    if (!verbose)
        printf("..................................................");
    printf("Test %s.\n", result ? "FAILED" : "PASSED");
    return result;
}