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