author | zecke <zecke> | 2005-01-09 16:27:40 (UTC) |
---|---|---|
committer | zecke <zecke> | 2005-01-09 16:27:40 (UTC) |
commit | ebd352b30b5b0278e613e1d1ecc60a5fc7756961 (patch) (side-by-side diff) | |
tree | 0a7967a8cf668bf06fd949fbc7e1c9c33043fc60 | |
parent | c6432d421a0ec3d158bf40309e98fc0386c4a287 (diff) | |
download | opie-ebd352b30b5b0278e613e1d1ecc60a5fc7756961.zip opie-ebd352b30b5b0278e613e1d1ecc60a5fc7756961.tar.gz opie-ebd352b30b5b0278e613e1d1ecc60a5fc7756961.tar.bz2 |
-Do not access the Array out of bounds
-Check that there is a driver before asking
to query a non existant
-rw-r--r-- | noncore/settings/networksettings2/opietooth2/OTGateway.cpp | 1 | ||||
-rw-r--r-- | noncore/settings/networksettings2/opietooth2/OTGateway.h | 2 |
2 files changed, 2 insertions, 1 deletions
diff --git a/noncore/settings/networksettings2/opietooth2/OTGateway.cpp b/noncore/settings/networksettings2/opietooth2/OTGateway.cpp index e8137dd..1b61a2e 100644 --- a/noncore/settings/networksettings2/opietooth2/OTGateway.cpp +++ b/noncore/settings/networksettings2/opietooth2/OTGateway.cpp @@ -1,531 +1,532 @@ #include <qmessagebox.h> #include <qfile.h> #include <qdir.h> #include <qtextstream.h> #include <qpixmap.h> #include <qvector.h> #include <qpe/resource.h> #include <opie2/odebug.h> #include <bluezlib.h> #include <OTDevice.h> #include <OTDriver.h> #include <OTInquiry.h> #include <OTDriverList.h> #include <OTDeviceAddress.h> #include <OTGateway.h> using namespace Opietooth2; // single instance OTGateway * OTGateway::SingleGateway = 0; int OTGateway::UseCount = 0; OTGateway * OTGateway::getOTGateway( void ) { if(SingleGateway == 0 ) { SingleGateway = new OTGateway(); } UseCount ++; return SingleGateway; } void OTGateway::releaseOTGateway( void ) { UseCount --; if( UseCount == 0 ) { delete SingleGateway; SingleGateway = 0; } } // open bluetooth system OTGateway::OTGateway( void ) : QObject( 0, "OTGateway" ), AllDrivers( this ), AllPeers() { ErrorConnectCount = 0; TheOTDevice = 0; Scanning = 0; AllPeersModified = 0; AllPeers.setAutoDelete( TRUE ); if ( ( HciCtl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { SLOT_ShowError( tr( "error opening hci socket" ) ); return; } // load all known devices updateDrivers(); // load all peers we have ever seen loadKnownPeers(); // iterate over drivers and find active connections // adding/updating peers loadActiveConnections(); // check every 4 seconds the state of BT timerEvent(0); RefreshTimer = -1; setRefreshTimer( 4000 ); // load known link keys readLinkKeys(); } // close bluetooth system OTGateway::~OTGateway( void ) { if( AllPeersModified ) { saveKnownPeers(); } if( Scanning ) delete Scanning; if( TheOTDevice ) delete TheOTDevice; if( HciCtl >= 0 ) { ::close( HciCtl ); } } void OTGateway::setRefreshTimer( int T ) { if( RefreshTimer != -1 ) { killTimer( RefreshTimer ); } if( T == 0 ) T = 4000; RefreshTimer = startTimer( T ); } OTDevice * OTGateway::getOTDevice( ) { if( TheOTDevice == 0 ) { // load bluetooth device and check state TheOTDevice = new OTDevice( this ); connect( TheOTDevice, SIGNAL( isEnabled( int, bool ) ), this, SLOT( SLOT_Enabled( int, bool ) ) ); connect( TheOTDevice, SIGNAL( error( const QString & ) ), this, SLOT( SLOT_ShowError( const QString & ) ) ); } return TheOTDevice; } // start bluetooth (if stopped) // return TRUE if started void OTGateway::SLOT_SetEnabled( bool Mode ) { if( Mode ) { SLOT_Enable(); return; } SLOT_Disable(); } void OTGateway::SLOT_Enable() { getOTDevice()->attach(); } void OTGateway::SLOT_Disable() { getOTDevice()->detach(); } bool OTGateway::needsEnabling() { return getOTDevice()->needsAttach(); } bool OTGateway::isEnabled() { if( getOTDevice()->deviceNr() >= 0 && + AllDrivers.count() != 0 && driver( getOTDevice()->deviceNr() )->isUp() ) return TRUE; // else check system return getOTDevice()->isAttached(); } void OTGateway::SLOT_ShowError( const QString & S ) { odebug << S << oendl; if( ErrorConnectCount > 0 ) { // pass error emit error( QString( "<p>" ) + S + "</p>" ); return; } QMessageBox::warning( 0, tr("OTGateway error"), S ); } void OTGateway::connectNotify( const char * S ) { if( S && strcmp( S, "error(const QString&)" ) == 0 ) { ErrorConnectCount ++; } } void OTGateway::disconnectNotify( const char * S ) { if( S && strcmp( S, "error(const QString&)" ) == 0 ) { ErrorConnectCount --; } } void OTGateway::timerEvent( QTimerEvent * ) { OTDriver * D; unsigned int oldc = AllDrivers.count(); bool old; AllDrivers.update(); if( oldc != AllDrivers.count() ) { updateDrivers(); } else { for( unsigned int i = 0; i < AllDrivers.count(); i ++ ) { D = AllDrivers[i]; old = D->isUp(); if( D->currentState() >= 0 ) { if( old != D->isUp() ) { emit stateChange( D, D->isUp() ); } } else { // if one driver is unable to provide info // we refresh all devices updateDrivers(); return; } } } } void OTGateway::SLOT_Enabled( int id, bool Up ) { odebug << "device " << id << " state " << Up << oendl; if( Up ) { // device is up -> detect it updateDrivers(); if( (unsigned)id >= AllDrivers.count() ) { // to make sure that the driver really IS detected AllDrivers[id]->bringUp(); } } // if DOWN device already down emit deviceEnabled( Up ); } void OTGateway::updateDrivers( void ) { OTDriver * D; AllDrivers.update(); odebug << "updated drivers. now " << AllDrivers.count() << oendl; // connect signals for each driver for( unsigned int i = 0; i < AllDrivers.count(); i ++ ) { D = AllDrivers[i]; connect( D, SIGNAL( error( const QString & ) ), this, SLOT( SLOT_ShowError( const QString & ) ) ); connect( D, SIGNAL( stateChange( OTDriver *, bool ) ), this, SIGNAL( stateChange( OTDriver *, bool ) ) ); connect( D, SIGNAL( driverDisappeared( OTDriver * ) ), this, SLOT( SLOT_DriverDisappeared( OTDriver * ) ) ); } // verify main device too if( TheOTDevice ) TheOTDevice->checkAttach(); // set to default scanning hardware setScanWith( 0 ); emit driverListChanged(); } void OTGateway::SLOT_DriverDisappeared( OTDriver * D ) { odebug << "Driver " << D->devname() << " when offline" << oendl; updateDrivers(); } void OTGateway::scanNeighbourhood( OTDriver * D ) { if( Scanning ) { stopScanOfNeighbourhood(); } if( D ) { setScanWith( D ); } Scanning = new OTInquiry( scanWith() ); connect( Scanning, SIGNAL( peerFound( OTPeer *, bool )), this, SLOT( SLOT_PeerDetected( OTPeer *, bool ) ) ); connect( Scanning, SIGNAL( finished()), this, SLOT( SLOT_FinishedDetecting() ) ); // start scanning Scanning->inquire( 30.0 ); } OTPeer* OTGateway::findPeer( const OTDeviceAddress & Addr ) { for( unsigned int i = 0 ; i < AllPeers.count(); i ++ ) { if( AllPeers[i]->address() == Addr ) { return AllPeers[i]; } } return 0; } OTDriver* OTGateway::findDriver( const OTDeviceAddress & Addr ) { for( unsigned int i = 0 ; i < AllDrivers.count(); i ++ ) { if( AllDrivers[i]->address() == Addr ) { return AllDrivers[i]; } } return 0; } void OTGateway::SLOT_PeerDetected( OTPeer * P, bool IsNew ) { if( IsNew ) { // new peer odebug << "New peer " << P->name() << oendl; addPeer( P ); } emit detectedPeer( P, IsNew ); } void OTGateway::addPeer( OTPeer * P ) { AllPeers.resize( AllPeers.size()+1); AllPeers.insert( AllPeers.size()-1, P ); AllPeersModified = 1; } void OTGateway::removePeer( OTPeer * P ) { int i = AllPeers.find( P ); if( i ) { AllPeers.remove( i ); AllPeersModified = 1; } } void OTGateway::stopScanOfNeighbourhood( void ) { if( Scanning ) { delete Scanning; Scanning = 0; } } void OTGateway::SLOT_FinishedDetecting() { stopScanOfNeighbourhood(); emit finishedDetecting(); } const char * OTGateway::deviceTypeToName( int cls ) { switch ( (cls & 0x001F00) >> 8) { case 0x00: return "misc"; case 0x01: return "computer"; case 0x02: return "phone"; case 0x03: return "lan"; case 0x04: return "av"; case 0x05: return "peripheral"; case 0x06: return "imaging"; case 0x07: default : break; } return "unknown"; } PANConnectionVector OTGateway::getPANConnections( void ) { PANConnectionVector V; struct bnep_connlist_req req; struct bnep_conninfo ci[48]; V.setAutoDelete(TRUE); int ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP); if (ctl < 0) { odebug << "Failed to open control socket" << oendl; return V; } req.cnum = 48; req.ci = ci; if (ioctl(ctl, BNEPGETCONNLIST, &req)) { odebug << "Failed to get connection list" << oendl; ::close( ctl ); return V; } for ( unsigned i=0; i < req.cnum; i++) { V.resize( V.size() + 1 ); if( ci[i].role == BNEP_SVC_PANU ) { // we are the client V.insert( V.size()-1, new OTPANConnection( ci[i].device, batostr((bdaddr_t *) ci[i].dst) ) ); } } ::close( ctl ); return V; } struct link_key { bdaddr_t sba; bdaddr_t dba; uint8_t key[16]; uint8_t type; time_t time; }; void OTGateway::readLinkKeys( void ) { struct link_key k; int rv; AllKeys.truncate(0); QFile F( "/etc/bluetooth/link_key" ); if( ! F.open( IO_ReadOnly ) ) { emit error( tr("Cannot open link_key file") ); return; } while( 1 ) { rv = F.readBlock( (char *)&k, sizeof( k ) ); if( rv == 0 ) // EOF break; if( rv < 0 ) { emit error( tr("Read error in link key file") ); } AllKeys.resize( AllKeys.size()+1 ); AllKeys[ AllKeys.size()-1 ].From.setBDAddr( k.sba ); AllKeys[ AllKeys.size()-1 ].To.setBDAddr( k.dba ); } } bool OTGateway::removeLinkKey( unsigned int Index ) { OTLinkKey & LK = AllKeys[Index]; struct link_key k; int rv; QFile F( "/etc/bluetooth/link_key" ); QFile OutF( "/etc/bluetooth/newlink_key" ); if( ! F.open( IO_ReadOnly ) ) { emit error( tr("Cannot open link_key file") ); return 0; } if( ! OutF.open( IO_WriteOnly | IO_Truncate ) ) { emit error( tr("Cannot open temporary link_key file") ); return 0; } while( 1 ) { rv = F.readBlock( (char *)&k, sizeof( k ) ); if( rv == 0 ) // EOF break; if( rv < 0 ) { emit error( tr("Read error in link key file") ); return 0; } if( LK.from() != OTDeviceAddress( k.sba ) || LK.to() != OTDeviceAddress( k.dba ) ) { // copy OutF.writeBlock( (char *)&k, sizeof( k ) ); } // else remove this key } // rename files QDir D( "/etc/bluetooth" ); D.remove( "link_key" ); D.rename( "newlink_key", "link_key" ); // restart hcid system( "/etc/init.d/hcid stop" ); system( "/etc/init.d/hcid start" ); // remove from table if( Index < (AllKeys.size()-1) ) { // collapse array AllKeys[Index] = AllKeys[AllKeys.size()-1]; } // remove last element AllKeys.resize( AllKeys.size()-1 ); return 1; } #define MAXCONNECTIONS 10 void OTGateway::loadActiveConnections( void ) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; OTDeviceAddress Addr; OTPeer * P; if (!(cl = (struct hci_conn_list_req *)malloc( MAXCONNECTIONS * sizeof(*ci) + sizeof(*cl)))) { emit error( tr("Can't allocate memory") ); return; } memset( cl, 0, MAXCONNECTIONS * sizeof(*ci) + sizeof(*cl) ); for( unsigned int i = 0; i < AllDrivers.count(); i ++ ) { if( ! AllDrivers[i]->isUp() ) { continue; diff --git a/noncore/settings/networksettings2/opietooth2/OTGateway.h b/noncore/settings/networksettings2/opietooth2/OTGateway.h index d97ef35..11c6b30 100644 --- a/noncore/settings/networksettings2/opietooth2/OTGateway.h +++ b/noncore/settings/networksettings2/opietooth2/OTGateway.h @@ -1,200 +1,200 @@ #ifndef OTGATEWAY_H #define OTGATEWAY_H #include <qobject.h> #include <qvector.h> #include <qmap.h> #include <OTDriverList.h> #include <OTInquiry.h> class QPixmap; namespace Opietooth2 { class OTDriverList; class OTDriver; class OTDevice; class OTPeer; class OTInquiry; class OTPANConnection; class OTLinkKey; typedef QVector<OTPeer> PeerVector; typedef QVector<OTPANConnection> PANConnectionVector; typedef QArray<OTLinkKey> LinkKeyArray; class OTLinkKey { public : OTLinkKey( const OTDeviceAddress & F, const OTDeviceAddress & T ) { From = F; To = T; } const OTDeviceAddress & to() { return To; } const OTDeviceAddress & from() { return From; } OTDeviceAddress From; OTDeviceAddress To; }; class OTPANConnection { public : OTPANConnection( const QString & Dev, const QString & CT ) { Device = Dev; ConnectedTo = CT; } QString Device; QString ConnectedTo; }; class OTGateway : public QObject { Q_OBJECT public : // single instance static OTGateway * getOTGateway( void ); static void releaseOTGateway( void ); // convert device type as class to name for that class static const char * deviceTypeToName( int Cls ); // open bluetooth system OTGateway( void ); // close bluetooth system ~OTGateway( void ); // get access to system device OTDevice * getOTDevice(); // return true if this device needs enabling of bluetooth bool needsEnabling(); // return true if system is running bool isEnabled(); void setRefreshTimer( int MilleSecs ); // return socket to HCI raw layer inline int getSocket() { return HciCtl; } OTDriverList & getDriverList() { return AllDrivers; } OTDriver * driver( int nr ) - { return AllDrivers[nr]; } + { return AllDrivers.count() == 0 ? 0 : AllDrivers[nr]; } void updateDrivers(); PANConnectionVector getPANConnections(); // scan neighbourhood using device void scanNeighbourhood( OTDriver * D = 0 ); void stopScanOfNeighbourhood(void ); void setScanWith( OTDriver * D = 0 ) { ScanWith = (D) ? D : (AllDrivers.count() ) ? AllDrivers[0] : 0; } OTDriver * scanWith( void ) { return ScanWith; } // get list of all detected peers inline const PeerVector & peers( void ) { return AllPeers; } // ping peer to see if it is up bool isPeerUp( const OTDeviceAddress & PAddr, int timeoutInSec = 1, int timeoutInUSec = 0, int retry = 1 ); OTPeer * findPeer( const OTDeviceAddress & Addr ); void removePeer( OTPeer * P ); void addPeer( OTPeer * P ); OTDriver * findDriver( const OTDeviceAddress & Addr ); inline const LinkKeyArray & getLinkKeys() const { return AllKeys; } bool removeLinkKey( unsigned int index ); // return device number if we are connected over any device // to the channel // else returns -1 int connectedToRFCommChannel( const OTDeviceAddress & Addr, int channel ); int getFreeRFCommDevice( void ); // return 0 if properly released int releaseRFCommDevice( int DevNr ); public slots : // start bluetooth system void SLOT_SetEnabled( bool ); void SLOT_Enable(); void SLOT_Disable(); // show error void SLOT_ShowError( const QString & ); void SLOT_Enabled( int, bool ); void SLOT_DriverDisappeared( OTDriver * ); void SLOT_PeerDetected( OTPeer *, bool ); void SLOT_FinishedDetecting(); signals : // any error void error( const QString & ); // signal state of bluetooth driver void stateChange( OTDriver * D, bool State ); // sent when list of drivers changees void driverListChanged(); // sent when bluetooth on device is enabled void deviceEnabled( bool ); // sent when a (new if bool = TRUE) peer is detected void detectedPeer( OTPeer *, bool ); // end of detection process void finishedDetecting(); protected : void connectNotify( const char * Signal ); void disconnectNotify( const char * Signal ); void timerEvent( QTimerEvent * ); private : void loadActiveConnections( void ); void loadKnownPeers( void ); void saveKnownPeers( void ); bool isConnectedTo( int devid, const OTDeviceAddress & Address ); void readLinkKeys(); static OTGateway * SingleGateway; static int UseCount; OTDriver * ScanWith; OTDriverList AllDrivers; OTDevice * TheOTDevice; int HciCtl; int ErrorConnectCount; int RefreshTimer; OTInquiry * Scanning; bool AllPeersModified; PeerVector AllPeers; LinkKeyArray AllKeys; }; } #endif |