/*
* Remote Laboratory FPGA Viewer Part
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* ( c ) 2012 Timothy Pearson
* Raptor Engineering
* http : //www.raptorengineeringinc.com
*/
# include "define.h"
# include "part.h"
# include <kaboutdata.h> //::createAboutData()
# include <kaction.h>
# include <klocale.h>
# include <kmessagebox.h> //::start()
# include <kparts/genericfactory.h>
# include <kstatusbar.h>
# include <kstdaction.h>
# include <tqfile.h> //encodeName()
# include <tqtimer.h> //postInit() hack
# include <tqvbox.h>
# include <tqsocket.h>
# include <tqmutex.h>
# include <tqeventloop.h>
# include <tqapplication.h>
# include <unistd.h> //access()
# include <stdint.h>
# include "tracewidget.h"
# include "floatspinbox.h"
# include "layout.h"
namespace RemoteLab {
typedef KParts : : GenericFactory < RemoteLab : : FPGAViewPart > Factory ;
# define CLIENT_LIBRARY "libremotelab_fpgaviewer"
K_EXPORT_COMPONENT_FACTORY ( libremotelab_fpgaviewer , RemoteLab : : Factory )
FPGAViewPart : : FPGAViewPart ( TQWidget * parentWidget , const char * widgetName , TQObject * parent , const char * name , const TQStringList & )
: ReadOnlyPart ( parent , name ) , m_socket ( 0 ) , m_base ( 0 ) , connToServerConnecting ( false ) , connToServerState ( - 1 ) , connToServerTimeoutTimer ( NULL )
{
// Initialize mutex
m_connectionMutex = new TQMutex ( false ) ;
// Initialize kpart
setInstance ( Factory : : instance ( ) ) ;
setWidget ( new TQVBox ( parentWidget , widgetName ) ) ;
// Create timers
m_updateTimer = new TQTimer ( this ) ;
// Create widgets
m_base = new FPGAViewBase ( widget ( ) ) ;
processLockouts ( ) ;
TQTimer : : singleShot ( 0 , this , TQT_SLOT ( postInit ( ) ) ) ;
}
FPGAViewPart : : ~ FPGAViewPart ( ) {
if ( m_connectionMutex - > locked ( ) ) {
printf ( " [WARNING] Exiting when data transfer still in progress! \n \r " ) ; fflush ( stdout ) ;
}
disconnectFromServer ( ) ;
delete m_connectionMutex ;
}
void FPGAViewPart : : processLockouts ( ) {
TQWidget * mainWidget = widget ( ) ;
if ( mainWidget ) {
if ( ( m_socket ) & & ( m_socket - > state ( ) = = TQSocket : : Connected ) ) {
mainWidget - > setEnabled ( true ) ;
}
else {
mainWidget - > setEnabled ( false ) ;
}
}
}
void FPGAViewPart : : connectionClosed ( ) {
closeURL ( ) ;
}
void FPGAViewPart : : postInit ( ) {
connect ( m_updateTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( updateDisplay ( ) ) ) ;
}
bool FPGAViewPart : : openURL ( const KURL & url ) {
int ret ;
ret = connectToServer ( url . url ( ) ) ;
processLockouts ( ) ;
return ( ret ! = 0 ) ;
}
bool FPGAViewPart : : closeURL ( ) {
disconnectFromServer ( ) ;
m_url = KURL ( ) ;
return true ;
}
void FPGAViewPart : : disconnectFromServer ( ) {
if ( m_socket ) {
m_socket - > clearPendingData ( ) ;
m_socket - > close ( ) ;
delete m_socket ;
m_socket = NULL ;
}
processLockouts ( ) ;
}
void FPGAViewPart : : finishConnectingToServer ( ) {
if ( connToServerConnecting ) {
switch ( connToServerState ) {
case 0 :
if ( ! connToServerTimeoutTimer ) {
connToServerTimeoutTimer = new TQTimer ;
connToServerTimeoutTimer - > start ( 5000 , TRUE ) ;
}
if ( ( m_socket - > state ( ) = = TQSocket : : Connecting ) | | ( m_socket - > state ( ) = = TQSocket : : HostLookup ) ) {
if ( ! connToServerTimeoutTimer - > isActive ( ) ) {
connToServerState = - 3 ;
connToServerConnecting = false ;
disconnectFromServer ( ) ;
KMessageBox : : error ( 0 , i18n ( " <qt>Unable to establish connection to remote server</qt> " ) , i18n ( " Connection Failed " ) ) ;
}
}
else {
if ( m_socket - > state ( ) = = TQSocket : : Connected ) {
printf ( " [DEBUG] Initial connection established... \n \r " ) ; fflush ( stdout ) ;
m_socket - > setDataTimeout ( 5000 ) ;
m_socket - > setUsingKerberos ( true ) ;
connToServerState = 1 ;
}
else {
connToServerState = - 1 ;
connToServerConnecting = false ;
disconnectFromServer ( ) ;
KMessageBox : : error ( 0 , i18n ( " <qt>Unable to establish connection to remote server</qt> " ) , i18n ( " Connection Failed " ) ) ;
}
}
break ;
case 1 :
if ( m_socket - > kerberosStatus ( ) = = TDEKerberosClientSocket : : KerberosInitializing ) {
// Do nothing
}
else {
if ( m_socket - > kerberosStatus ( ) ! = TDEKerberosClientSocket : : KerberosInUse ) {
connToServerState = - 1 ;
connToServerConnecting = false ;
disconnectFromServer ( ) ;
KMessageBox : : error ( 0 , i18n ( " <qt>Unable to establish Kerberos protocol with remote server<p>Please verify that you currently hold a valid Kerberos ticket</qt> " ) , i18n ( " Connection Failed " ) ) ;
}
else {
connToServerState = 2 ;
}
}
break ;
case 2 :
// Connection established!
// Read magic number and proto version from server
TQDataStream ds ( m_socket ) ;
TQ_UINT32 magicnum ;
TQ_UINT32 protover ;
ds > > magicnum ;
ds > > protover ;
printf ( " [DEBUG] Got magic number %d and protocol version %d \n \r " , magicnum , protover ) ; fflush ( stdout ) ;
// Request connection to backend server
TQString response ;
ds < < TQString ( " SERV " ) ;
ds < < TQString ( CLIENT_LIBRARY ) ;
ds > > response ;
printf ( " [RAJA DEBUG 400.0] Got '%s' from the server \n \r " , response . ascii ( ) ) ; fflush ( stdout ) ;
if ( response = = " OK " ) {
connToServerState = 3 ;
connToServerConnecting = false ;
processLockouts ( ) ;
return ;
}
else if ( response = = " ERRNOCONN " ) {
connToServerState = - 1 ;
connToServerConnecting = false ;
disconnectFromServer ( ) ;
KMessageBox : : error ( 0 , i18n ( " <qt>Unable to establish connection with backend server<p>Please verify that you are currently connected to a workspace</qt> " ) , i18n ( " Connection Failed " ) ) ;
return ;
}
else if ( response = = " ERRNOTAVL " ) {
connToServerState = - 1 ;
connToServerConnecting = false ;
disconnectFromServer ( ) ;
KMessageBox : : error ( 0 , i18n ( " <qt>The backend server is not available at this time<p>Please try a different workspace, or try again later</qt> " ) , i18n ( " Connection Failed " ) ) ;
return ;
}
else if ( response = = " ERRNOSERV " ) {
connToServerState = - 1 ;
connToServerConnecting = false ;
disconnectFromServer ( ) ;
KMessageBox : : error ( 0 , i18n ( " <qt>The active laboratory workspace does not support the requested service</qt> " ) , i18n ( " Service Unavailable " ) ) ;
return ;
}
else {
connToServerState = - 1 ;
connToServerConnecting = false ;
disconnectFromServer ( ) ;
KMessageBox : : error ( 0 , i18n ( " <qt>Unable to establish connection with remote server</qt> " ) , i18n ( " Connection Failed " ) ) ;
return ;
}
break ;
}
TQTimer : : singleShot ( 0 , this , SLOT ( finishConnectingToServer ( ) ) ) ;
}
}
int FPGAViewPart : : connectToServer ( TQString server ) {
if ( m_socket ) {
return - 1 ;
}
if ( ! m_socket ) {
m_socket = new TDEKerberosClientSocket ( this ) ;
}
m_socket - > setServiceName ( " remotefpga " ) ;
m_socket - > setServerFQDN ( server ) ;
m_socket - > connectToHost ( server , 4004 ) ;
// Finish connecting when appropriate
connToServerState = 0 ;
connToServerConnecting = true ;
TQTimer : : singleShot ( 0 , this , SLOT ( finishConnectingToServer ( ) ) ) ;
return 0 ;
}
void FPGAViewPart : : updateDisplay ( ) {
// RAJA FIXME
}
KAboutData * FPGAViewPart : : createAboutData ( ) {
return new KAboutData ( APP_NAME , I18N_NOOP ( APP_PRETTYNAME ) , APP_VERSION ) ;
}
} //namespace RemoteLab
# include "part.moc"