// // Serial Daemon // Neal Probert // #include #include #include #include #include #include #include #include #include #include #include #include "UriParse.h" #include "SerialDaemon.h" #include "netlib.h" //**************************************************************************** // defines //***************************************************************************/ //**************************************************************************** // macros //***************************************************************************/ //**************************************************************************** // structs & typedefs //***************************************************************************/ //**************************************************************************** // global constants //***************************************************************************/ //**************************************************************************** // global variables //***************************************************************************/ //**************************************************************************** // static constants //***************************************************************************/ //**************************************************************************** // static variables //***************************************************************************/ //**************************************************************************** // static functions //***************************************************************************/ //**************************************************************************** // C++ functions //***************************************************************************/ SerialDaemon::SerialDaemon() { // logging log_open( SERIALD_NAME ); m_SerialIn = m_RemoteIn = m_DgramIn = -1; m_framed = 0; bzero(m_Framing,sizeof(m_Framing)); } SerialDaemon::~SerialDaemon() { if ( m_SerialIn >= 0 ) close( m_SerialIn ); } /* TCP ***********************************************************************/ int SerialDaemon::ServerSocket(void) { char buf[2048]; int n = 0; if ( IsSet( m_RemoteIn ) ) { // from server n = Client.Recv( buf, sizeof(buf) ); if ( n > 0 ) { // send frame if ( m_framed ) { m_Framing[m_framed-2] = n >> 8; m_Framing[m_framed-1] = n; write( m_SerialIn, m_Framing, m_framed ); } // send data write( m_SerialIn, buf, n ); } } else if ( IsSet( m_SerialIn ) ) { // data from device n = read( m_SerialIn, buf, sizeof(buf) ); // parse data if ( n>0 ) ClientCast( buf, n ); } else if ( IsSet( m_DgramIn ) ) { // packet from UDP broadcast n = Dgram.RecvFrom( buf, sizeof(buf) ); // send to device if ( n > 0 ) { // send frame if ( m_framed ) { m_Framing[m_framed-2] = n >> 8; m_Framing[m_framed-1] = n; write( m_SerialIn, m_Framing, m_framed ); } // send data write( m_SerialIn, buf, n ); } } return n; } int SerialDaemon::ClientIn( int sock, const char *buf, int n ) { return write( m_SerialIn, buf, n ); } void SerialDaemon::ClientCast( const char *buf, int n ) { // broadcast it Bcast.SendTo( buf, n ); // send to clients TcpServer::ClientCast( buf, n ); } /* GPS ***********************************************************************/ int SerialDaemon::SerialOpen( const char *device, int baud ) { UriParse parsed; parsed.setRate( baud ); parsed.setUri( device ); int binary = 0; // parse type if ( strlen( parsed.getProto() ) ) { if ( strcasecmp( parsed.getProto(), "binary" ) == 0 ) binary = 1; } // open device m_SerialIn = serial_open( (char*)parsed.getPath(), parsed.getRate(), binary, binary?1:0 ); // check if ( m_SerialIn < 0 ) return m_SerialIn; // add listener AddFd( m_SerialIn ); return m_SerialIn; } int SerialDaemon::TcpConnect( const char *uri ) { UriParse parsed; parsed.setUri( uri ); const char *proto = parsed.getProto(); if ( strcasecmp( proto, "http" ) == 0 || strcasecmp( proto, "https" ) == 0 ) { // web site } else if ( strcasecmp( proto, "telnet" ) == 0 || strlen( proto ) == 0 ) { // straight TCP client m_RemoteIn = Client.Connect( parsed.getHost(), parsed.getService() ); } return m_RemoteIn; } int SerialDaemon::UdpListen( const char *uri ) { m_DgramIn = Dgram.ListenUri( uri ); if ( m_DgramIn > 0 ) AddFd( m_DgramIn ); return m_DgramIn; } int SerialDaemon::UdpBroadcast( const char *uri ) { return Bcast.CasterUri( uri ); } void SerialDaemon::SetFrame( const char *frame, int n ) { if ( n ) { // string strncpy( m_Framing, frame, sizeof(m_Framing)-2 ); m_framed = strlen(m_Framing)+2; } else { // hex unsigned long value = atol( frame ); m_framed = 6; m_Framing[0] = value >> 24; m_Framing[1] = value >> 16; m_Framing[2] = value >> 8; m_Framing[3] = value; } }