Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ocopclient.cpp

Go to the documentation of this file.
00001 #include <errno.h>
00002 #include <stdlib.h>
00003 #include <stdio.h>
00004 #include <unistd.h>
00005 #include <sys/socket.h>
00006 #include <sys/types.h>
00007 #include <sys/un.h>
00008 
00009 
00010 #include <qfile.h>
00011 #include <qtimer.h>
00012 
00013 #include "../common/ocoppacket.h"
00014 
00015 #include "ocopclient.h"
00016 
00017 OCOPClient* OCOPClient::m_self = 0;
00018 
00019 OCOPClient*  OCOPClient::self() {
00020     if (!m_self ) {
00021         m_self = new OCOPClient();
00022     }
00023     return m_self;
00024 }
00025 
00026 OCOPClient::OCOPClient( const QString& path, QObject* obj )
00027     : QObject( obj )
00028 {
00029     m_tries = 0;
00030     init(QFile::encodeName(path) );
00031 }
00032 OCOPClient::~OCOPClient() {
00033     delete m_notify;
00034     close( m_socket );
00035 }
00036 void OCOPClient::init() {
00037     // failed start ther server NOW!!!
00038     startUP();
00039     QCString str;
00040     init(str );
00041 }
00042 void OCOPClient::init( const QCString&  ) {
00043     m_tries++;
00044     struct sockaddr_un unix_adr;
00045     if ( (m_socket = socket(PF_UNIX, SOCK_STREAM, 0) ) < 0 ) {
00046         qWarning("could not socket");
00047         if ( m_tries < 8 )
00048             QTimer::singleShot(400, this,SLOT(init() ) );
00049         return;
00050     }
00051     memset(&unix_adr, 0, sizeof(unix_adr ) );
00052     unix_adr.sun_family = AF_UNIX;
00053     sprintf(unix_adr.sun_path,"%s/.opie.cop",  getenv("HOME") );
00054     int length = sizeof(unix_adr.sun_family) + strlen(unix_adr.sun_path);
00055 
00056     if ( ::connect(m_socket,  (struct sockaddr*)&unix_adr, length ) < 0 ) {
00057         qWarning("could not connect %d", errno );
00058         close( m_socket );
00059         if ( m_tries < 8 )
00060             QTimer::singleShot(400, this, SLOT(init() ) );
00061         return;
00062     }
00063     m_notify = new QSocketNotifier(m_socket, QSocketNotifier::Read, this );
00064     connect( m_notify, SIGNAL(activated(int) ),
00065              this, SLOT(newData() ) );
00066 }
00072 void OCOPClient::newData() {
00073     OCOPPacket pack = packet();
00074     if ( pack.channel().isEmpty() )
00075         return;
00076 
00077     switch( pack.type() ) {
00078     case OCOPPacket::Register:
00079     case OCOPPacket::Unregister:
00080     case OCOPPacket::Method:
00081     case OCOPPacket::RegisterChannel:
00082     case OCOPPacket::UnregisterChannel:
00083     case OCOPPacket::Return:
00084     case OCOPPacket::Signal:
00085         /* is Registered should be handled sync */
00086     case OCOPPacket::IsRegistered:
00087         break;
00088         /* emit the signal */
00089     case OCOPPacket::Call:
00090         emit called( pack.channel(), pack.header(), pack.content() );
00091         break;
00092     }
00093 }
00094 OCOPPacket OCOPClient::packet() const{
00095     QCString chan;
00096     QCString func;
00097     QByteArray ar;
00098     OCOPHead head;
00099     memset(&head, 0, sizeof(head) );
00100     read(m_socket, &head, sizeof(head) );
00101     if ( head.magic == 47 ) {
00102 //        qWarning("Client:Magic Match");
00103         chan = QCString( head.chlen+1);
00104         func = QCString( head.funclen+1 );
00105         ar = QByteArray( head.datalen);
00106         read(m_socket, chan.data(), head.chlen );
00107         read(m_socket, func.data(), head.funclen );
00108         read(m_socket, ar.data(), head.datalen );
00109 //      qWarning("Client:%d %s",head.chlen,chan.data() );
00110     }
00111     OCOPPacket pack(head.type, chan,  func, ar );
00112     return pack;
00113 }
00114 /*
00115  * we've blocking IO here on these sockets
00116  * so we send and go on read
00117  * this will be blocked
00118  */
00119 bool OCOPClient::isRegistered( const QCString& chan ) const{
00120 //    qWarning("OCopClient::isRegistered %s", chan.data() );
00121     /* should I disconnect the socket notfier? */
00122     OCOPPacket packe(OCOPPacket::IsRegistered, chan );
00123     OCOPHead head = packe.head();
00124     write(m_socket, &head, sizeof(head) );
00125     write(m_socket, chan.data(), chan.size() );
00126     /* block */
00127     OCOPPacket pack = packet();
00128     qWarning("unblock %s %s", pack.channel().data(), chan.data() );
00129 
00130     /* connect here again */
00131     if ( pack.channel() == chan ) {
00132         QCString func = pack.header();
00133         if (func[0] == 1 )
00134             return true;
00135     }
00136 
00137     return false;
00138 };
00139 void OCOPClient::send( const QCString& chan, const QCString& fu, const QByteArray& arr ) {
00140 //    qWarning("ClientSending %s %s", chan.data(), fu.data() );
00141     OCOPPacket pack(OCOPPacket::Call, chan, fu, arr );
00142     call( pack );
00143 }
00144 void OCOPClient::addChannel(const QCString& channel) {
00145     OCOPPacket pack(OCOPPacket::RegisterChannel, channel );
00146     call( pack );
00147 }
00148 void OCOPClient::delChannel(const QCString& chan ) {
00149     OCOPPacket pack(OCOPPacket::UnregisterChannel, chan );
00150     call( pack );
00151 }
00152 void OCOPClient::call( const OCOPPacket& pack ) {
00153     OCOPHead head = pack.head();
00154     write(m_socket, &head, sizeof(head) );
00155     write(m_socket, pack.channel().data(), pack.channel().size() );
00156     write(m_socket, pack.header().data(), pack.header().size() );
00157     write(m_socket, pack.content().data(), pack.content().size() );
00158 }
00159 void OCOPClient::startUP() {
00160     qWarning("Start me up");
00161     pid_t pi = fork();
00162     if ( pi == 0 ) {
00163         setsid();
00164         execlp("ocopserver", "ocopserver", NULL );
00165         _exit(1);
00166     }
00167 }

Generated on Sat Nov 5 16:18:35 2005 for OPIE by  doxygen 1.4.2