Пример #1
0
static void *remote_connect_sync_thread( void *data )
{
	net_response_t *response;
	net_ctx_t *ctx = NULL;
	char *remote_service_name = NULL;
	int shutdown_fd = 0;
	fd_set read_fds;
	struct timeval tv;
	int sync_interval = 0;

	logging_printf( LOGGING_DEBUG, "remote_connect_sync_thread: start\n");
	logging_printf( LOGGING_DEBUG, "rmeote_connect_sync_thread: sync.interval=%s\n", config_string_get("sync.interval"));

	shutdown_fd = net_socket_get_shutdown_fd();
	logging_printf( LOGGING_DEBUG, "remote_connect_sync_thread: shutdown_fd=%u\n", shutdown_fd );

	remote_service_name = config_string_get("remote.connect");
	sync_interval = config_int_get("sync.interval");

	do
	{
		ctx = net_ctx_find_by_name( remote_service_name );
		if( ! ctx )
		{
			logging_printf( LOGGING_DEBUG, "remote_connect_sync_thread: No remote connection context\n");
			break;
		}
		FD_ZERO( &read_fds );
		FD_SET( shutdown_fd, &read_fds );
		memset( &tv, 0, sizeof( struct timeval ) );
		tv.tv_sec = sync_interval;
		select( shutdown_fd + 1, &read_fds, NULL , NULL, &tv );
		logging_printf( LOGGING_DEBUG, "remote_connect_sync_thread: select()=\"%s\"\n", strerror( errno ) );
		if( net_socket_get_shutdown_lock() == 1 )
		{
			logging_printf(LOGGING_DEBUG, "remote_connect_sync_thread: shutdown received during poll\n");
			break;
		}
		response = net_response_sync( ctx->send_ssrc , ctx->start );
		net_ctx_send( ctx, response->buffer, response->len, USE_CONTROL_PORT );
		hex_dump( response->buffer, response->len );
		net_response_destroy( &response );
	} while( 1 );

	if( net_socket_get_shutdown_lock() == 1 )
	{
		logging_printf(LOGGING_DEBUG, "remote_connect_sync_thread: shutdown received\n");
	}
	logging_printf( LOGGING_DEBUG, "remote_connect_sync_thread: stop\n");

	return NULL;
}
Пример #2
0
void remote_connect_init( void )
{
	dns_service_t *found_service = NULL;
	char *remote_service_name = NULL;
	char *client_name = NULL;
	net_response_t *response = NULL;
	net_ctx_t *ctx;
	int use_ipv4, use_ipv6;
	uint32_t initiator = 0, ssrc = 0;
	char *p1 = NULL;
	char *p2 = NULL;
	int remote_port_number = 0;


	if( ! config_is_set( "remote.connect" ) )
	{
		logging_printf(LOGGING_WARN, "remote_connect_init: Called with no remote.connect value\n");
		return;
	}

	remote_service_name = (char *) strdup( config_string_get("remote.connect") );

	logging_printf(LOGGING_DEBUG, "remote_connect_init: Looking for [%s]\n", remote_service_name);

	p1 = remote_service_name;
	p2 = p1 + strlen( remote_service_name );

	/* Work backwards to find a colon ':' */
	/* If a ']' character is found first, we'll assume this is going to be an direct connect address */

	while( p2 > p1 )
	{
		if( *p2 == ']' ) break;
		if( *p2 == ':' ) break;
		p2--;
	}



	/* If no colon ':' or ']' was found, we'll assume this is a service name to be located */
	if( p2 == p1 )
	{
		use_ipv4 = is_yes( config_string_get("service.ipv4") ) ;
		use_ipv6 = is_yes( config_string_get("service.ipv6") ) ;

		if( dns_discover_services( use_ipv4, use_ipv6 ) <= 0 )
		{
			logging_printf(LOGGING_WARN, "remote_connect_init: No services available\n");
			free( remote_service_name );
			return;
		}

		found_service = dns_discover_by_name( remote_service_name );
		goto make_remote_connection;
	}  else {
		/* If there is a colon ':', split the string to determine the port number */
		if( *p2 == ':' )
		{
			*p2='\0';
			p2++;
			remote_port_number = atoi( p2 );
			p2 = remote_service_name + strlen( remote_service_name ) - 1;
		}

		/* If there is a ']', work forwards from the start of the string to remove the '[' */
		if ( *p2 == ']' )
		{
			*p2='\0';
			while( p1 < p2 )
			{
				if( *p1 == '[' ) break;
				p1++;
			}

		}
		if( p1 == p2 )
		{
			p1 = remote_service_name;
		} else {
			*p1='\0';
			p1++;
		}

		if( remote_port_number == 0 )
		{
			logging_printf( LOGGING_ERROR, "remote_connect_init: No port number specified\n");
			free( remote_service_name );
			return;
		}

		logging_printf( LOGGING_DEBUG, "remote_connect_init: connect_string=>%s<\n", config_string_get("remote.connect") );
		logging_printf( LOGGING_DEBUG, "remote_connect_init: connect_address=>%s<, connect_port=%d\n", p1, remote_port_number );

		dns_discover_add( config_string_get("remote.connect"), p1, remote_port_number );
		found_service = dns_discover_by_name( config_string_get("remote.connect") );
	}
	

make_remote_connection:
	free( remote_service_name );

	if( ! found_service )
	{
		logging_printf(LOGGING_WARN, "remote_connect_init: No service found: %s\n", remote_service_name );
		return;
	}

	logging_printf( LOGGING_DEBUG, "remote_connect_init: Found name=\"%s\" address=[%s]:%d\n", found_service->name, found_service->ip_address, found_service->port);
	ssrc = random_number();
	initiator = random_number();

	client_name = config_string_get("service.name");

	if( !client_name )
	{
		client_name = "RaveloxMIDIClient";
	}

	response = net_response_inv( ssrc, initiator, client_name );

	if( response )
	{
		ctx = net_ctx_register( ssrc, initiator, found_service->ip_address, found_service->port, found_service->name );

		if( ! ctx )
		{
			logging_printf( LOGGING_ERROR, "remote_connect_init: Unable to create socket context\n");
		} else {
			ctx->send_ssrc = ssrc;
			ctx->status = NET_CTX_STATUS_FIRST_INV;
			logging_printf( LOGGING_DEBUG, "remote_connect_init: Sending INV request to [%s]:%d\n", ctx->ip_address, ctx->control_port );
			net_ctx_send( ctx, response->buffer, response->len , USE_CONTROL_PORT );
		}
	}

	net_response_destroy( &response );
}
Пример #3
0
void remote_connect_teardown( void )
{
	net_applemidi_inv *by = NULL;
	net_response_t *response = NULL;
	net_applemidi_command *cmd = NULL;
	char *remote_service_name = NULL;
	net_ctx_t *ctx;

	remote_service_name = config_string_get("remote.connect");

	logging_printf( LOGGING_DEBUG, "remote_connect_teardown: Disconnecting from [%s]\n", remote_service_name);

	remote_connect_wait_for_thread();

	ctx = net_ctx_find_by_name( remote_service_name );
	
	if( ! ctx )
	{
		logging_printf( LOGGING_ERROR, "remote_connect_teardown: Unable to find connection for [%s]\n", remote_service_name);
		return;
	};

	// Build the BY packet
	by = net_applemidi_inv_create();
	
	if( ! by )
	{
		logging_printf( LOGGING_ERROR, "remote_connect_teardown: Unable to allocate memory for by packet\n");
		return;
	}

	by->ssrc = ctx->send_ssrc;
	by->version = 2;
	by->initiator = ctx->initiator;

	cmd = net_applemidi_cmd_create( NET_APPLEMIDI_CMD_END );
	
	if( ! cmd ) 
	{
		logging_printf( LOGGING_ERROR, "remote_connect_teardown: Unable to create AppleMIDI command\n");
		net_applemidi_inv_destroy( &by );
		goto remote_teardown_fail;
	}

	cmd->data = by;

	response = net_response_create();

	if( response )
	{
		int ret = 0;
		ret = net_applemidi_pack( cmd , &(response->buffer), &(response->len) );
		if( ret != 0 )
		{
			logging_printf( LOGGING_ERROR, "remote_connect_teardown: Unable to pack response to by command\n");
		} else {
			net_ctx_send( ctx, response->buffer, response->len , USE_CONTROL_PORT);
			hex_dump( response->buffer, response->len );
		}
	} else {
		logging_printf( LOGGING_ERROR, "remote_connect_teardown: Unable to create response packet\n");
	}

remote_teardown_fail:
	net_response_destroy( &response );
	net_applemidi_cmd_destroy( &cmd );
}
Пример #4
0
net_response_t * cmd_inv_handler( char *ip_address, uint16_t port, void *data )
{
	net_applemidi_command *cmd = NULL;
	net_applemidi_inv *inv = NULL;
	net_applemidi_inv *accept_inv = NULL;
	net_ctx_t *ctx = NULL;
	net_response_t *response;
	char *service_name = NULL;

	if( ! data ) return NULL;

	inv = ( net_applemidi_inv *) data;

	logging_printf( LOGGING_DEBUG, "INV(%s:%u\n ", ip_address, port );

	logging_printf( LOGGING_DEBUG, "\tname=%s\n", inv->name);
	logging_printf( LOGGING_DEBUG, "\tssrc=0x%08x\n", inv->ssrc);
	logging_printf( LOGGING_DEBUG, "\tversion=0x%08x\n", inv->version);
	logging_printf( LOGGING_DEBUG, "\tinitiator=0x%08x )\n", inv->initiator);

	ctx = net_ctx_find_by_ssrc( inv->ssrc );

	if( ! ctx )
	{
		logging_printf( LOGGING_DEBUG, "cmd_inv_hander: Registering new connection\n");
		ctx = net_ctx_register( inv->ssrc, inv->initiator, ip_address, port );

		if( ! ctx ) 
		{
			logging_printf( LOGGING_ERROR, "cmd_inv_handler: Error registering connection\n");
		}
	}

	cmd = new_net_applemidi_command( NET_APPLEMIDI_CMD_ACCEPT );

	if( ! cmd )
	{
		logging_printf( LOGGING_ERROR, "Unable to allocate memory for accept_inv command\n");
		net_ctx_reset( ctx );
		return NULL;
	}

	accept_inv = new_net_applemidi_inv();
	
	if( ! accept_inv ) {
		logging_printf( LOGGING_ERROR, "Unabled to allocate memory for accept_inv command data\n");
		free( cmd );
		net_ctx_reset( ctx );
		return NULL;
	}

	accept_inv->ssrc = ctx->send_ssrc;
	accept_inv->version = 2;
	accept_inv->initiator = ctx->initiator;
	service_name = config_get("service.name");
	if( service_name )
	{
		accept_inv->name = (char *)strdup( service_name );
	} else {
		accept_inv->name = (char *)strdup( "RaveloxMIDI" );
	}

	cmd->data = accept_inv;

	response = new_net_response();

	if( response )
	{
		int ret = 0;
		ret = net_applemidi_pack( cmd , &(response->buffer), &(response->len) );
		if( ret != 0 )
		{
			logging_printf( LOGGING_ERROR, "Unable to pack response to inv command\n");
			net_response_destroy( &response );
		}
	}

	net_applemidi_cmd_destroy( &cmd );

	return response;
}