Ejemplo n.º 1
0
/* Called on head of multibus group */
void serial_free(struct connection_in *connection)
{
    FILE_DESCRIPTOR_OR_ERROR fd ;
    struct port_in * pin = connection->pown ;

    if ( pin->state == cs_virgin ) {
        return ;
    }

    fd = pin->file_descriptor ;
    if ( FILE_DESCRIPTOR_NOT_VALID( fd ) ) {
        // reopen to restore attributes
        fd = open( pin->init_data, O_RDWR | O_NONBLOCK | O_NOCTTY ) ;
    }

    // restore tty settings
    if ( FILE_DESCRIPTOR_VALID( fd ) ) {
        LEVEL_DEBUG("COM_close: flush");
        tcflush( fd, TCIOFLUSH);
        LEVEL_DEBUG("COM_close: restore");
        if ( tcsetattr( fd, TCSANOW, &(pin->dev.serial.oldSerialTio) ) < 0) {
            ERROR_CONNECT("Cannot restore port attributes: %s", pin->init_data);
        }
    }
    Test_and_Close( &( pin->file_descriptor) ) ;
}
Ejemplo n.º 2
0
static void * ENET_monitor_loop( void * v )
{
	struct connection_in * in = v ;
	FILE_DESCRIPTOR_OR_ERROR file_descriptor = in->master.enet_monitor.shutdown_pipe[fd_pipe_read] ;

	DETACH_THREAD;
	
	do {
		fd_set readset;
		struct timeval tv = { in->master.enet_monitor.enet_scan_interval, 0, };
		
		/* Initialize readset */
		FD_ZERO(&readset);
		if ( FILE_DESCRIPTOR_VALID( file_descriptor ) ) {
			FD_SET(file_descriptor, &readset);
		}

		ENET_scan_for_adapters() ;

		if ( select( file_descriptor+1, &readset, NULL, NULL, &tv ) != 0 ) {
			break ; // don't scan any more -- perhaps a close?
		}
	} while (1) ;
	
	return VOID_RETURN ;
}
Ejemplo n.º 3
0
static void ENET_monitor_close(struct connection_in *in)
{
	if ( FILE_DESCRIPTOR_VALID( in->master.enet_monitor.shutdown_pipe[fd_pipe_write] ) ) {
		ignore_result = write( in->master.enet_monitor.shutdown_pipe[fd_pipe_write],"X",1) ; //dummy payload
	}		
	Test_and_Close_Pipe(in->master.enet_monitor.shutdown_pipe) ;
}
Ejemplo n.º 4
0
/* Usually called with BUS locked, to protect ai settings */
FILE_DESCRIPTOR_OR_ERROR ClientConnect(struct connection_in *in)
{
	struct port_in * pin = in->pown ;
	FILE_DESCRIPTOR_OR_ERROR file_descriptor;
	struct addrinfo *ai;

	if ( pin->dev.tcp.ai == NULL) {
		LEVEL_DEBUG("Client address not yet parsed");
		return FILE_DESCRIPTOR_BAD;
	}

	/* Can't change ai_ok without locking the in-device.
	 * First try the last working address info, if it fails lock
	 * the in-device and loop through the list until it works.
	 * Not a perfect solution, but it should work at least.
	 */
	ai = pin->dev.tcp.ai_ok;
	if (ai) {
		file_descriptor = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if ( FILE_DESCRIPTOR_VALID(file_descriptor) ) {
			if (connect(file_descriptor, ai->ai_addr, ai->ai_addrlen) == 0) {
				return file_descriptor;
			}
			close(file_descriptor);
		}
	}

	ai = pin->dev.tcp.ai;		// loop from first address info since it failed.
	do {
		file_descriptor = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if ( FILE_DESCRIPTOR_VALID(file_descriptor) ) {
			if (connect(file_descriptor, ai->ai_addr, ai->ai_addrlen) == 0) {
				pin->dev.tcp.ai_ok = ai;
				return file_descriptor;
			}
			close(file_descriptor);
		}
	} while ((ai = ai->ai_next));
	pin->dev.tcp.ai_ok = NULL;

	ERROR_CONNECT("Socket problem");
	STAT_ADD1(NET_connection_errors);
	return FILE_DESCRIPTOR_BAD;
}
Ejemplo n.º 5
0
/* Called on head of multibus group */
GOOD_OR_BAD COM_read( BYTE * data, size_t length, struct connection_in *connection)
{
	struct port_in * pin ;
	
	if ( length == 0 ) {
		return gbGOOD ;
	}
	
	if ( connection == NO_CONNECTION || data == NULL ) {
		// bad parameters
		return gbBAD ;
	}
	pin = connection->pown ;

	// unlike write or open, a closed connection isn't automatically opened.
	// the reason is that reopening won't have the data waiting. We really need
	// to restart the transaction from the "write" portion
	if ( FILE_DESCRIPTOR_NOT_VALID( pin->file_descriptor ) ) {
		return gbBAD ;
	}

	switch ( pin->type ) {
		// test the type of connection
		case ct_unknown:
		case ct_none:
			LEVEL_DEBUG("Unknown type");
			break ;
		case ct_telnet:
			return telnet_read( data, length, connection ) ;
		case ct_tcp:
			// network is ok
			return COM_read_get_size( data, length, connection ) == (ssize_t) length ? gbGOOD : gbBAD ;
		case ct_i2c:
		case ct_netlink:
		case ct_usb:
			LEVEL_DEBUG("Unimplemented");
			break ; 
		case ct_serial:
		// serial is ok
		// printf("Serial read fd=%d length=%d\n",pin->file_descriptor, (int) length);
		{
			ssize_t actual = COM_read_get_size( data, length, connection ) ;
			if ( FILE_DESCRIPTOR_VALID( pin->file_descriptor ) ) {
				// tcdrain only works on serial conections
				tcdrain( pin->file_descriptor );
				return actual == (ssize_t) length ? gbGOOD : gbBAD ;
			}
			break ;
		}
	}
	return gbBAD ;
}
Ejemplo n.º 6
0
void FreeOutAll(void)
{
	struct connection_out *next = Outbound_Control.head;
	struct connection_out *now;

	Outbound_Control.head = NULL;
	Outbound_Control.active = 0;
	while (next) {
		now = next;
		next = now->next;
		SAFEFREE(now->zero.name) ;
		SAFEFREE(now->zero.type) ;
		SAFEFREE(now->zero.domain) ;
		SAFEFREE(now->name) ;
		SAFEFREE(now->host) ;
		SAFEFREE(now->service) ;
		if (now->ai) {
			freeaddrinfo(now->ai);
			now->ai = NULL;
		}
		if ( FILE_DESCRIPTOR_VALID(now->file_descriptor) ) {
			shutdown(now->file_descriptor, SHUT_RDWR ) ;
			close(now->file_descriptor) ;
		}
#if OW_ZERO
		if (libdnssd != NULL) {
			if (now->sref0) {
				DNSServiceRefDeallocate(now->sref0);
			}
			if (now->sref1) {
				DNSServiceRefDeallocate(now->sref1);
			}
		}
#endif
		owfree(now);
	}
}
Ejemplo n.º 7
0
// Wait for a resolve, then return. Timeout after 2 minutes
static void ResolveWait( DNSServiceRef sref )
{
	FILE_DESCRIPTOR_OR_ERROR file_descriptor = DNSServiceRefSockFD(sref);

	if ( FILE_DESCRIPTOR_VALID(file_descriptor) ) {
		while (1) {
			fd_set readfd;
			struct timeval tv = { 120, 0 };

			FD_ZERO(&readfd);
			FD_SET(file_descriptor, &readfd);
			if (select(file_descriptor + 1, &readfd, NULL, NULL, &tv) > 0) {
				if (FD_ISSET(file_descriptor, &readfd)) {
					DNSServiceProcessResult(sref);
				}
			} else if (errno == EINTR) {
				continue;
			} else {
				ERROR_CONNECT("Resolve timeout error");
			}
			break;
		}
	}
}