summaryrefslogtreecommitdiff
path: root/noncore/net/opietooth/manager/rfcommhelper.cpp
authorharlekin <harlekin>2002-07-22 21:39:08 (UTC)
committer harlekin <harlekin>2002-07-22 21:39:08 (UTC)
commit0433711d6f7190073c476a2f771dfce879ef87e5 (patch) (side-by-side diff)
tree1f7e1f90aefd9e96ec2011b98baff3524d9e787d /noncore/net/opietooth/manager/rfcommhelper.cpp
parent41182706349e2ab92afbb7a5cc635e672cccf065 (diff)
downloadopie-0433711d6f7190073c476a2f771dfce879ef87e5.zip
opie-0433711d6f7190073c476a2f771dfce879ef87e5.tar.gz
opie-0433711d6f7190073c476a2f771dfce879ef87e5.tar.bz2
wrapper arround rfcomm command line tool
Diffstat (limited to 'noncore/net/opietooth/manager/rfcommhelper.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/opietooth/manager/rfcommhelper.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/noncore/net/opietooth/manager/rfcommhelper.cpp b/noncore/net/opietooth/manager/rfcommhelper.cpp
new file mode 100644
index 0000000..0769da2
--- a/dev/null
+++ b/noncore/net/opietooth/manager/rfcommhelper.cpp
@@ -0,0 +1,181 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+
+#include "rfcommhelper.h"
+
+using namespace OpieTooth;
+
+bool RfCommHelper::terminate = false;
+pid_t RfCommHelper::m_pid;
+
+RfCommHelper::RfCommHelper()
+ : m_connected( false )
+{
+ signal( SIGCHLD, signal_handler );
+}
+RfCommHelper::~RfCommHelper() {
+ detach();
+}
+QCString RfCommHelper::attachedDevice() const {
+ return m_device;
+}
+void RfCommHelper::detach() {
+ if (m_connected )
+ ::kill( m_pid, 9 );
+ if ( m_in2out[0] )
+ close(m_in2out[0] );
+ if ( m_in2out[1] )
+ close(m_in2out[1] );
+ if ( m_out2in[0] )
+ close(m_out2in[0] );
+ if ( m_out2in[1] )
+ close(m_out2in[1] );
+}
+bool RfCommHelper::attach( const QString& bd_addr, int port ) {
+ int i =0;
+ bool ok = false;
+ while (!ok ) {
+ if (i == 4) break;
+ ok = connect( i, bd_addr, port );
+ i++;
+ }
+ return ok;
+}
+/*
+ * not implemented yet
+ */
+void RfCommHelper::regroup() {
+
+}
+bool RfCommHelper::connect(int devi, const QString& bdaddr, int port) {
+ m_connected = false;
+ if ( pipe(m_fd) < 0 )
+ m_fd[0] = m_fd[1] = 0;
+ if ( pipe(m_in2out) < 0 )
+ m_in2out[0] = m_in2out[1] = 0;
+ if ( pipe(m_out2in ) < 0 )
+ m_out2in[0] = m_out2in[1] = 0;
+
+ m_pid = fork();
+ switch( m_pid ) {
+ case -1:
+ return false;
+ break;
+ /*
+ * This is the child code.
+ * We do some fd work
+ * and then we'll execlp
+ * to start it up
+ */
+ case 0:{ // child code
+ setupComChild();
+ char por[15];
+ char dev[15];
+ sprintf( por, "%d", port );
+ sprintf( dev, "%d", devi );
+ execlp( "rfcomm", "rfcomm", dev, bdaddr.latin1(), por, NULL );
+ char resultByte = 1;
+ if ( m_fd[1] )
+ write(m_fd[1], &resultByte, 1 );
+ _exit( -1 );
+ break;
+ }
+ /*
+ * The Parent. We'll first wait for fd[0] to fill
+ * up.
+ * Then we will wait for out2in[0] to fill up and then
+ * we will parse it.
+ * maybe the signal handler gets it's turn in this case we return
+ * false
+ * otheriwse we will parse the Output and either return true
+ * or false
+ */
+ default: {
+ if ( m_fd[1] )
+ close( m_fd[1] );
+ if ( m_fd[0] ) for (;;) {
+ char resultByte;
+ int len;
+ len = read(m_fd[0], &resultByte, 1 );
+ if ( len == 1 ) { // it failed to execute
+ return false;
+ }
+ if ( len == -1 )
+ if ( (errno == ECHILD ) || (errno == EINTR ) )
+ continue; // the other process is not yet ready?
+
+ break;
+ }
+ if ( m_fd[0] )
+ close( m_fd[0] );
+ terminate = false;
+ fd_set fds;
+ struct timeval timeout;
+ int sel;
+ while (!terminate ) {
+ FD_ZERO( &fds );
+ FD_SET( m_in2out[0], &fds );
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+
+ sel = select( m_in2out[0]+1, &fds, NULL, NULL, &timeout );
+ if ( sel )
+ if (FD_ISSET(m_in2out[0], &fds ) ) {
+ char buf[2048];
+ int len;
+ buf[0] = 0;
+ len = read( m_in2out[0], buf, sizeof(buf) );
+ if ( len > 0 ) {
+ QCString string( buf );
+ if (string.left(9) == "Connected" ) {
+ m_connected = true;
+ m_device = m_device.sprintf("/dev/tty%d", devi );
+ break; // we got connected
+ };
+ }
+ // now parese it
+ }else {// time out
+ // 5 seconds without input check terminate?
+ //
+ ;
+ }
+ }
+ break;
+ }
+ }
+ return !terminate;
+}
+
+
+void RfCommHelper::setupComChild() {
+ if ( m_fd[0] )
+ close(m_fd[0]);
+ if ( m_fd[1] )
+ fcntl( m_fd[1] , F_SETFD, FD_CLOEXEC);
+
+ /* duplicating pipes and making them STDIN and STDOUT
+ * of the new process
+ * [0] is for reading
+ * [1] is for writing
+ */
+ dup2( m_out2in[0], STDIN_FILENO );
+ dup2( m_in2out[1], STDOUT_FILENO );
+
+
+};
+void RfCommHelper::signal_handler(int) {
+ int status;
+ terminate = true;
+ signal( SIGCHLD, signal_handler );
+ waitpid( m_pid, &status, WNOHANG );
+}