summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/opietooth/manager/manager.pro4
-rw-r--r--noncore/net/opietooth/manager/rfcommhelper.cpp181
-rw-r--r--noncore/net/opietooth/manager/rfcommhelper.h69
3 files changed, 253 insertions, 1 deletions
diff --git a/noncore/net/opietooth/manager/manager.pro b/noncore/net/opietooth/manager/manager.pro
index 4684c67..d3c69e0 100644
--- a/noncore/net/opietooth/manager/manager.pro
+++ b/noncore/net/opietooth/manager/manager.pro
@@ -7,17 +7,19 @@ HEADERS = btconnectionitem.h btdeviceitem.h \
7 scandialog.h btlistitem.h \ 7 scandialog.h btlistitem.h \
8 hciconfwrapper.h bticonloader.h \ 8 hciconfwrapper.h bticonloader.h \
9 pppdialog.h obexdialog.h \ 9 pppdialog.h obexdialog.h \
10 devicehandler.h rfcpopup.h obexpopup.h \ 10 devicehandler.h rfcpopup.h obexpopup.h \
11 rfcommhelper.h
11 12
12SOURCES = btconnectionitem.cpp btdeviceitem.cpp \ 13SOURCES = btconnectionitem.cpp btdeviceitem.cpp \
13 btserviceitem.cpp stdpopups.cpp \ 14 btserviceitem.cpp stdpopups.cpp \
14 popuphelper.cpp main.cpp \ 15 popuphelper.cpp main.cpp \
15 bluebase.cpp scandialog.cpp \ 16 bluebase.cpp scandialog.cpp \
16 btlistitem.cpp hciconfwrapper.cpp \ 17 btlistitem.cpp hciconfwrapper.cpp \
17 bticonloader.cpp pppdialog.cpp \ 18 bticonloader.cpp pppdialog.cpp \
18 obexdialog.cpp devicehandler.cpp \ 19 obexdialog.cpp devicehandler.cpp \
19 rfcpopup.cpp obexpopup.cpp 20 rfcpopup.cpp obexpopup.cpp \
21 rfcommhelper.cpp
20INCLUDEPATH += $(OPIEDIR)/include 22INCLUDEPATH += $(OPIEDIR)/include
21INCLUDEPATH += $(OPIEDIR)/noncore/net/opietooth/lib 23INCLUDEPATH += $(OPIEDIR)/noncore/net/opietooth/lib
22DEPENDPATH += $(OPIEDIR)/include 24DEPENDPATH += $(OPIEDIR)/include
23LIBS += -lqpe -lopietooth -lopie 25LIBS += -lqpe -lopietooth -lopie
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 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include <errno.h>
4#include <signal.h>
5
6#include <stdio.h>
7#include <stdlib.h>
8
9#include <sys/types.h>
10#include <sys/time.h>
11#include <sys/wait.h>
12
13
14#include "rfcommhelper.h"
15
16using namespace OpieTooth;
17
18bool RfCommHelper::terminate = false;
19pid_t RfCommHelper::m_pid;
20
21RfCommHelper::RfCommHelper()
22 : m_connected( false )
23{
24 signal( SIGCHLD, signal_handler );
25}
26RfCommHelper::~RfCommHelper() {
27 detach();
28}
29QCString RfCommHelper::attachedDevice() const {
30 return m_device;
31}
32void RfCommHelper::detach() {
33 if (m_connected )
34 ::kill( m_pid, 9 );
35 if ( m_in2out[0] )
36 close(m_in2out[0] );
37 if ( m_in2out[1] )
38 close(m_in2out[1] );
39 if ( m_out2in[0] )
40 close(m_out2in[0] );
41 if ( m_out2in[1] )
42 close(m_out2in[1] );
43}
44bool RfCommHelper::attach( const QString& bd_addr, int port ) {
45 int i =0;
46 bool ok = false;
47 while (!ok ) {
48 if (i == 4) break;
49 ok = connect( i, bd_addr, port );
50 i++;
51 }
52 return ok;
53}
54/*
55 * not implemented yet
56 */
57void RfCommHelper::regroup() {
58
59}
60bool RfCommHelper::connect(int devi, const QString& bdaddr, int port) {
61 m_connected = false;
62 if ( pipe(m_fd) < 0 )
63 m_fd[0] = m_fd[1] = 0;
64 if ( pipe(m_in2out) < 0 )
65 m_in2out[0] = m_in2out[1] = 0;
66 if ( pipe(m_out2in ) < 0 )
67 m_out2in[0] = m_out2in[1] = 0;
68
69 m_pid = fork();
70 switch( m_pid ) {
71 case -1:
72 return false;
73 break;
74 /*
75 * This is the child code.
76 * We do some fd work
77 * and then we'll execlp
78 * to start it up
79 */
80 case 0:{ // child code
81 setupComChild();
82 char por[15];
83 char dev[15];
84 sprintf( por, "%d", port );
85 sprintf( dev, "%d", devi );
86 execlp( "rfcomm", "rfcomm", dev, bdaddr.latin1(), por, NULL );
87 char resultByte = 1;
88 if ( m_fd[1] )
89 write(m_fd[1], &resultByte, 1 );
90 _exit( -1 );
91 break;
92 }
93 /*
94 * The Parent. We'll first wait for fd[0] to fill
95 * up.
96 * Then we will wait for out2in[0] to fill up and then
97 * we will parse it.
98 * maybe the signal handler gets it's turn in this case we return
99 * false
100 * otheriwse we will parse the Output and either return true
101 * or false
102 */
103 default: {
104 if ( m_fd[1] )
105 close( m_fd[1] );
106 if ( m_fd[0] ) for (;;) {
107 char resultByte;
108 int len;
109 len = read(m_fd[0], &resultByte, 1 );
110 if ( len == 1 ) { // it failed to execute
111 return false;
112 }
113 if ( len == -1 )
114 if ( (errno == ECHILD ) || (errno == EINTR ) )
115 continue; // the other process is not yet ready?
116
117 break;
118 }
119 if ( m_fd[0] )
120 close( m_fd[0] );
121 terminate = false;
122 fd_set fds;
123 struct timeval timeout;
124 int sel;
125 while (!terminate ) {
126 FD_ZERO( &fds );
127 FD_SET( m_in2out[0], &fds );
128 timeout.tv_sec = 5;
129 timeout.tv_usec = 0;
130
131 sel = select( m_in2out[0]+1, &fds, NULL, NULL, &timeout );
132 if ( sel )
133 if (FD_ISSET(m_in2out[0], &fds ) ) {
134 char buf[2048];
135 int len;
136 buf[0] = 0;
137 len = read( m_in2out[0], buf, sizeof(buf) );
138 if ( len > 0 ) {
139 QCString string( buf );
140 if (string.left(9) == "Connected" ) {
141 m_connected = true;
142 m_device = m_device.sprintf("/dev/tty%d", devi );
143 break; // we got connected
144 };
145 }
146 // now parese it
147 }else {// time out
148 // 5 seconds without input check terminate?
149 //
150 ;
151 }
152 }
153 break;
154 }
155 }
156 return !terminate;
157}
158
159
160void RfCommHelper::setupComChild() {
161 if ( m_fd[0] )
162 close(m_fd[0]);
163 if ( m_fd[1] )
164 fcntl( m_fd[1] , F_SETFD, FD_CLOEXEC);
165
166 /* duplicating pipes and making them STDIN and STDOUT
167 * of the new process
168 * [0] is for reading
169 * [1] is for writing
170 */
171 dup2( m_out2in[0], STDIN_FILENO );
172 dup2( m_in2out[1], STDOUT_FILENO );
173
174
175};
176void RfCommHelper::signal_handler(int) {
177 int status;
178 terminate = true;
179 signal( SIGCHLD, signal_handler );
180 waitpid( m_pid, &status, WNOHANG );
181}
diff --git a/noncore/net/opietooth/manager/rfcommhelper.h b/noncore/net/opietooth/manager/rfcommhelper.h
new file mode 100644
index 0000000..545998c
--- a/dev/null
+++ b/noncore/net/opietooth/manager/rfcommhelper.h
@@ -0,0 +1,69 @@
1
2#ifndef OPIETOOTH_RFCOMM_HELPER_H
3#define OPIETOOTH_RFCOMM_HELPER_H
4
5#include <sys/types.h>
6
7#include <qcstring.h>
8#include <qstring.h>
9
10namespace OpieTooth {
11 /**
12 * RfCommHelper helps to attach to a remote
13 * channel of a bt device.
14 * It uses the commandline tool rfcomm fo the job
15 * it tries to attach to afree node and either succeeds
16 * or fails.
17 * Later RfCommHelper can be used to detach the device
18 * from the remote device
19 */
20 class RfCommHelper {
21 public:
22 /**
23 * c'tor
24 */
25 RfCommHelper();
26
27 /**
28 * d'tor removes the device
29 */
30 ~RfCommHelper(); // kills the process
31
32 /**
33 * gives the device name of the attached device
34 */
35 QCString attachedDevice() const;
36
37 /**
38 * detach a device
39 * kills the rfcomm process
40 */
41 void detach();
42
43 /**
44 * tries to connect to a remote device
45 * @param bd_addr the bluetooth address
46 * @param port The port of the remote device
47 */
48 bool attach(const QString& bd_addr, int port );
49
50 /**
51 * If the original user of the bond exists
52 * it may regroup the rfcomm process
53 */
54 void regroup();
55 private:
56 bool connect( int dev, const QString& bdaddr, int port );
57 static void signal_handler(int);
58 void setupComChild();
59 bool m_connected:1;
60 static pid_t m_pid;
61 QCString m_device;
62 int m_fd[2];
63 int m_in2out[2];
64 int m_out2in[2];
65 static bool terminate ;
66 };
67};
68
69#endif