Пример #1
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 );
}
Пример #2
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;
}