/*
 *  Handles error or log messages from the frame buffer library.
 *  We route these back to all clients in an ERROR packet.  Note that
 *  this is a replacement for the default fb_log function in libfb
 *  (which just writes to stderr).
 *
 *  Log an FB library event, when _doprnt() is not available.
 *  This version should work on practically any machine, but
 *  it serves to highlight the grossness of the varargs package
 *  requiring the size of a parameter to be known at compile time.
 */
void
fb_log( const char *fmt, ... )
{
    va_list ap;
    char	outbuf[OUTBUFSZ];			/* final output string */
    int	want;
    int	i;
    int	nsent = 0;

    va_start( ap, fmt );
    (void)vsprintf( outbuf, fmt, ap );
    va_end(ap);

    want = strlen(outbuf)+1;
    for ( i = MAX_CLIENTS-1; i >= 0; i-- )  {
	if ( clients[i] == NULL )  continue;
	if ( pkg_send( MSG_ERROR, outbuf, want, clients[i] ) != want )  {
	    comm_error("pkg_send error in fb_log, message was:\n");
	    comm_error(outbuf);
	} else {
	    nsent++;
	}
    }
    if ( nsent == 0 || verbose )  {
	/* No PKG connection open yet! */
	fputs( outbuf, stderr );
	fflush(stderr);
    }
}
Exemple #2
0
void LOW_link::writeData( const uint8_t inSendByte, const strongPullup_t inPullup)
{
  commLock lock( *this);

  if ( touchByte( inSendByte, inPullup) != inSendByte )
    throw comm_error( "Response not equal to sent byte", __FILE__, __LINE__);
}
Exemple #3
0
void LOW_link::writeData( const bool inSendBit, const strongPullup_t inPullup)
{
  commLock lock( *this);

  if ( touchBit( inSendBit, inPullup) != inSendBit )
    throw comm_error( "Response not equal to sent bit", __FILE__, __LINE__);
}
Exemple #4
0
void LOW_link::writeData( const byteVec_t &inSendBytes, const strongPullup_t inPullup)
{
  commLock lock( *this);

  byteVec_t readVec = touchBlock( inSendBytes, inPullup);

  for( unsigned int i=0; i<inSendBytes.size(); i++)
    if ( readVec[i] != inSendBytes[i] ) {
      throw comm_error( "Response not equal to sent byte", __FILE__, __LINE__);
    }
}
bool LOW_linkPassiveSerial::resetBus()
{
  commLock lock( *this);
  
  const uint8_t   resetSendByte = 0xF0;
  
  bool            devFound = false;
    
  try {
    
    // Flush the input and output buffers
    serialPort->tty_flush();
    
    serialPort->tty_configure( LOW_portSerial::none_flowControl, LOW_portSerial::bit8_size, 
                               LOW_portSerial::no_parity, LOW_portSerial::bit1_stopBit, LOW_portSerial::B10472_speed);
    
    // Send the reset pulse
    serialPort->tty_write( resetSendByte);

    uint8_t tmpByte = serialPort->tty_readByte();

    if( tmpByte == 0 )  // if answer is still zero, then it is a short to ground
      throw comm_error( "Possible short to ground detected", __FILE__, __LINE__);

    // If the byte read is not what we sent, check for an error
    // For now just return a 1 and discount any errors??
    if( tmpByte != resetSendByte )
      devFound = true; // got a response of some type
    else
      devFound = false; // no device responding
  }
  catch( ... ) {
    
    try { 
      serialPort->tty_configure( LOW_portSerial::none_flowControl, LOW_portSerial::bit6_size, 
                                 LOW_portSerial::no_parity, LOW_portSerial::bit1_stopBit, LOW_portSerial::B115200_speed);
    }
    catch( ... ) {}
    
    throw;
  }  
  
  serialPort->tty_configure( LOW_portSerial::none_flowControl, LOW_portSerial::bit6_size, 
                             LOW_portSerial::no_parity, LOW_portSerial::bit1_stopBit, LOW_portSerial::B115200_speed);

  return devFound;
}
int
main(int argc, char **argv)
{
#define PORTSZ 32
    char	portname[PORTSZ];

    max_fd = 0;

    /* No disk files on remote machine */
    _fb_disk_enable = 0;
    memset((void *)clients, 0, sizeof(struct pkg_conn *) * MAX_CLIENTS);

#ifdef SIGALRM
    (void)signal( SIGPIPE, SIG_IGN );
    (void)signal( SIGALRM, sigalarm );
#endif
    /*alarm(1)*/

    FD_ZERO(&select_list);
    fb_server_select_list = &select_list;
    fb_server_max_fd = &max_fd;

#ifndef _WIN32
    /*
     * Inetd Daemon.
     * Check to see if we were invoked by /etc/inetd.  If so
     * we will have an open network socket on fd=0.  Become
     * a Transient PKG server if this is so.
     */
    netfd = 0;
    if ( is_socket(netfd) ) {
	init_syslog();
	new_client( pkg_transerver( fb_server_pkg_switch, comm_error ) );
	max_fd = 8;
	once_only = 1;
	main_loop();
	return 0;
    }
#endif

    /* for now, make them set a port_num, for usage message */
    if ( !get_args( argc, argv ) || !port_set ) {
	(void)fputs(usage, stderr);
	return 1;
    }

    /* Single-Frame-Buffer Server */
    if ( framebuffer != NULL ) {
	fb_server_retain_on_close = 1;	/* don't ever close the frame buffer */

	/* open a frame buffer */
	if ( (fb_server_fbp = fb_open(framebuffer, width, height)) == FB_NULL )
	    bu_exit(1, NULL);
	max_fd = fb_set_fd(fb_server_fbp, &select_list);

	/* check/default port */
	if ( port_set ) {
	    if ( port < 1024 )
		port += 5559;
	}
	snprintf(portname, PORTSZ, "%d", port);

	/*
	 * Hang an unending listen for PKG connections
	 */
	if ( (netfd = pkg_permserver(portname, 0, 0, comm_error)) < 0 )
	    bu_exit(-1, NULL);
	FD_SET(netfd, &select_list);
	V_MAX(max_fd, netfd);

	main_loop();
	return 0;
    }

#ifndef _WIN32
    /*
     * Stand-Alone Daemon
     */
    /* check/default port */
    if ( port_set ) {
	if ( port < 1024 )
	    port += 5559;
	sprintf(portname, "%d", port);
    } else {
	snprintf(portname, PORTSZ, "%s", "remotefb");
    }

    init_syslog();
    while ( (netfd = pkg_permserver(portname, 0, 0, comm_error)) < 0 ) {
	static int error_count=0;
	sleep(1);
	if (error_count++ < 60) {
	    continue;
	}
	comm_error("Unable to start the stand-alone framebuffer daemon after 60 seconds, giving up.");
	return 1;
    }

    while (1) {
	int fbstat;
	struct pkg_conn	*pcp;

	pcp = pkg_getclient( netfd, fb_server_pkg_switch, comm_error, 0 );
	if ( pcp == PKC_ERROR )
	    break;		/* continue is unlikely to work */

	if ( fork() == 0 )  {
	    /* 1st level child process */
	    (void)close(netfd);	/* Child is not listener */

	    /* Create 2nd level child process, "double detach" */
	    if ( fork() == 0 )  {
		/* 2nd level child -- start work! */
		new_client( pcp );
		once_only = 1;
		main_loop();
		return 0;
	    } else {
		/* 1st level child -- vanish */
		return 1;
	    }
	} else {
	    /* Parent: lingering server daemon */
	    pkg_close(pcp);	/* Daemon is not the server */
	    /* Collect status from 1st level child */
	    (void)wait( &fbstat );
	}
    }
#endif  /* _WIN32 */

    return 2;
}