00001 #include <qdir.h>
00002 #include <qfileinfo.h>
00003
00004 #include <bluezlib.h>
00005
00006
00007 #include <opie2/odevice.h>
00008 #include <opie2/oprocess.h>
00009 #include <opie2/odebug.h>
00010
00011 #include <OTDevice.h>
00012
00013 using namespace Opie::Core;
00014 using namespace Opietooth2;
00015 using Opie::Core::OProcess;
00016
00017 OTDevice::OTDevice( OTGateway * _OT ) : QObject(0, "device") {
00018
00019
00020 OT = _OT;
00021
00022
00023 QString a, b;
00024 unsigned long c;
00025 detectDeviceType( a, b, c );
00026
00027 if( needsAttach() ) {
00028
00029
00030 m_hciattachPid = getPidOfHCIAttach();
00031
00032 m_hciattach = 0;
00033
00034 if( m_hciattachPid == 0 ) {
00035
00036 m_deviceNr = -1;
00037 } else {
00038
00039
00040
00041 m_deviceNr = 0;
00042 }
00043 } else {
00044 m_deviceNr = 0;
00045 }
00046 }
00047
00048 OTDevice::~OTDevice(){
00049 if( needsAttach() && m_hciattach ) {
00050
00051 m_hciattach->detach();
00052 delete m_hciattach;
00053 }
00054 }
00055
00056 bool OTDevice::attach(){
00057
00058 if( needsAttach() && m_hciattachPid == 0 ) {
00059 QString Dev, Mode;
00060 unsigned long Spd;
00061
00062 detectDeviceType( Dev, Mode, Spd );
00063
00064
00065 m_hciattach = new OProcess();
00066 *m_hciattach << "hciattach";
00067 *m_hciattach << "-p";
00068 *m_hciattach << Dev
00069 << Mode
00070 << QString().setNum(Spd);
00071
00072 connect( m_hciattach,
00073 SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int ) ),
00074 this, SLOT
00075 (slotStdOut(Opie::Core::OProcess*,char*,int) ) );
00076
00077 connect( m_hciattach,
00078 SIGNAL(receivedStderr(Opie::Core::OProcess*, char*, int ) ),
00079 this, SLOT
00080 (slotStdErr(Opie::Core::OProcess*,char*,int) ) );
00081
00082
00083
00084 if( ! m_hciattach->start( OProcess::DontCare,
00085 OProcess::AllOutput
00086 ) ){
00087 emit error( tr( "Could not start hciattach" ) );
00088 delete m_hciattach;
00089 m_hciattach = 0;
00090 return FALSE;
00091 }
00092 }
00093
00094 return TRUE;
00095 }
00096
00097 bool OTDevice::detach(){
00098
00099 if( needsAttach() && m_hciattachPid ) {
00100 if( m_hciattach ) {
00101 delete m_hciattach;
00102 m_hciattach = 0;
00103 }
00104
00105 if( kill( m_hciattachPid, 9) < 0 ) {
00106 odebug << "could not stop " << errno << oendl;
00107 emit error( tr( "Could not stop process" ) );
00108 return FALSE;
00109 }
00110 m_hciattachPid = 0;
00111 emit isEnabled( m_deviceNr, 0 );
00112 m_deviceNr = -1;
00113 }
00114
00115 return TRUE;
00116 }
00117
00118 bool OTDevice::isAttached()const{
00119 return ! needsAttach() || m_hciattachPid != 0;
00120 }
00121
00122 bool OTDevice::checkAttach(){
00123 if( ! needsAttach() ) {
00124 m_deviceNr = 0;
00125 emit isEnabled( 0, 1 );
00126 return TRUE;
00127 }
00128
00129 if( m_hciattachPid ) {
00130 QString S;
00131 S.setNum( m_hciattachPid );
00132 QDir D( "/proc" );
00133 if( !D.exists( S ) ) {
00134
00135 m_hciattachPid = 0;
00136 emit isEnabled( m_deviceNr, 0 );
00137 m_deviceNr = -1;
00138 }
00139 } else {
00140
00141 m_hciattachPid = getPidOfHCIAttach();
00142 if ( m_hciattachPid ) {
00143 m_deviceNr = 0;
00144 emit isEnabled( m_deviceNr, 1 );
00145 }
00146 }
00147 return m_hciattachPid != 0;
00148 }
00149
00150 void OTDevice::slotStdOut(OProcess* proc, char* , int ) {
00151 if( proc == m_hciattach ) {
00152 m_hciattach->detach();
00153
00154
00155
00156
00157 if( m_deviceNr == -1 ) {
00158 m_deviceNr = 0;
00159 emit isEnabled( m_deviceNr, 1 );
00160 }
00161 }
00162 }
00163
00164 void OTDevice::slotStdErr(OProcess* proc, char* chars, int len) {
00165
00166 if(proc == m_hciattach && len >= 1 ){
00167
00168 QCString string( chars, len+1 );
00169 QString m_output;
00170 m_output.append( string.data() );
00171 odebug << m_output << oendl;
00172 }
00173 }
00174
00175 pid_t OTDevice::getPidOfHCIAttach( void ) {
00176
00177 if( needsAttach() ) {
00178
00179
00180 QRegExp R("[0-9]+");
00181 QDir ProcDir( "/proc" );
00182 QFileInfo FI;
00183 QStringList EL = ProcDir.entryList( QDir::Dirs );
00184
00185
00186 for ( QStringList::Iterator it = EL.begin();
00187 it != EL.end();
00188 ++it ) {
00189 if( R.match( (*it) ) >= 0 ) {
00190
00191
00192
00193 FI.setFile( ProcDir.path()+"/"+ (*it) + "/exe" );
00194
00195
00196 if( FI.readLink().right( 9 ) == "hciattach" ) {
00197
00198
00199 return (*it).toULong();
00200 break;
00201 }
00202 }
00203 }
00204 }
00205
00206 return 0;
00207 }
00208
00209 void OTDevice::detectDeviceType( QString & Device,
00210 QString & Mode,
00211 unsigned long & Speed ) {
00212
00213
00214 odebug << "Detecting device" << oendl;
00215 switch ( ODevice::inst()->model() ) {
00216 case Model_iPAQ_H39xx:
00217 Device = "/dev/tts/1";
00218 Mode = "bcsp";
00219 Speed = 921600;
00220 NeedsAttach = 1;
00221 break;
00222
00223 case Model_iPAQ_H5xxx:
00224 Device = "/dev/tts/1";
00225 Mode = "any";
00226 Speed = 921600;
00227 NeedsAttach = 1;
00228 break;
00229
00230 case Model_GenuineIntel :
00231 Device = "";
00232 Mode = "";
00233 Speed = 0;
00234 NeedsAttach = 0;
00235 break;
00236
00237 default:
00238 Device = "/dev/ttySB0";
00239 Mode = "bcsp";
00240 Speed = 230400;
00241 NeedsAttach = 1;
00242 break;
00243 }
00244 }
00245
00246 QString OTDevice::getRFCommDevicePattern( void ) {
00247
00248 QDir D( "/dev/bluetooth/rfcomm" );
00249 if( D.exists() ) {
00250
00251 return QString( "/dev/bluetooth/rfcomm/%1" );
00252 }
00253
00254
00255 return QString( "/dev/rfcomm%1" );
00256 }