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
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
00086 case OCOPPacket::IsRegistered:
00087 break;
00088
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
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
00110 }
00111 OCOPPacket pack(head.type, chan, func, ar );
00112 return pack;
00113 }
00114
00115
00116
00117
00118
00119 bool OCOPClient::isRegistered( const QCString& chan ) const{
00120
00121
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
00127 OCOPPacket pack = packet();
00128 qWarning("unblock %s %s", pack.channel().data(), chan.data() );
00129
00130
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
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 }