summaryrefslogtreecommitdiff
path: root/libopie2/opienet
authorskyhusker <skyhusker>2005-04-20 10:20:20 (UTC)
committer skyhusker <skyhusker>2005-04-20 10:20:20 (UTC)
commitf6b9c85c09692f298ffa5ee95e1f171a9e158502 (patch) (side-by-side diff)
treed147bc5b67eb9bc3c7f042a4fa2fb1868d37faef /libopie2/opienet
parent6ec538f7e4a84e4f76addaf558c415b7dffc659b (diff)
downloadopie-f6b9c85c09692f298ffa5ee95e1f171a9e158502.zip
opie-f6b9c85c09692f298ffa5ee95e1f171a9e158502.tar.gz
opie-f6b9c85c09692f298ffa5ee95e1f171a9e158502.tar.bz2
Added function to set the associated AP address. Some improvements to scanNetwork(): read the signal quality, AP rates and fix channel reading when driver reports values < 1000.
Diffstat (limited to 'libopie2/opienet') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/onetwork.cpp38
-rw-r--r--libopie2/opienet/onetwork.h3
-rw-r--r--libopie2/opienet/ostation.h2
3 files changed, 38 insertions, 5 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index 546be9e..0a74019 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -17,63 +17,65 @@
    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
..}^=.=       =       ; Library General Public License for more
++=   -.     .`     .: details.
 :     =  ...= . :.=-
 -.   .:....=;==+<; You should have received a copy of the GNU
  -_. . .   )=.  = Library General Public License along with
    --        :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/* OPIE */
#include <opie2/onetwork.h>
#include <opie2/ostation.h>
#include <opie2/odebug.h>
/* QT */
#include <qfile.h>
#include <qtextstream.h>
+#include <qapplication.h>
/* UNIX */
#include <assert.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/sockios.h>
#include <net/if_arp.h>
+#include <net/ethernet.h>
#include <stdarg.h>
#ifndef NODEBUG
#include <opie2/odebugmapper.h>
using namespace Opie::Core;
using namespace Opie::Net::Internal;
DebugMapper* debugmapper = new DebugMapper();
#endif
/*======================================================================================
* ONetwork
*======================================================================================*/
namespace Opie {
namespace Net {
ONetwork* ONetwork::_instance = 0;
ONetwork::ONetwork()
{
odebug << "ONetwork::ONetwork()" << oendl;
odebug << "ONetwork: This code has been compiled against Wireless Extensions V" << WIRELESS_EXT << oendl;
synchronize();
}
@@ -470,48 +472,56 @@ OWirelessNetworkInterface::~OWirelessNetworkInterface()
struct iwreq& OWirelessNetworkInterface::iwr() const
{
return _iwr;
}
void OWirelessNetworkInterface::init()
{
odebug << "OWirelessNetworkInterface::init()" << oendl;
memset( &_iwr, 0, sizeof( struct iwreq ) );
buildInformation();
buildPrivateList();
dumpInformation();
}
bool OWirelessNetworkInterface::isAssociated() const
{
//FIXME: handle different modes
return !(associatedAP() == OMacAddress::unknown);
}
+void OWirelessNetworkInterface::setAssociatedAP( const OMacAddress& mac ) const
+{
+ _iwr.u.ap_addr.sa_family = ARPHRD_ETHER;
+ ::memcpy(_iwr.u.ap_addr.sa_data, mac.native(), ETH_ALEN);
+ wioctl( SIOCSIWAP );
+}
+
+
OMacAddress OWirelessNetworkInterface::associatedAP() const
{
if ( ioctl( SIOCGIWAP ) )
return (const unsigned char*) &_ifr.ifr_hwaddr.sa_data[0];
else
return OMacAddress::unknown;
}
void OWirelessNetworkInterface::buildInformation()
{
//ML: If you listen carefully enough, you can hear lots of WLAN drivers suck
//ML: The HostAP drivers need more than sizeof struct_iw range to complete
//ML: SIOCGIWRANGE otherwise they fail with "Invalid Argument Length".
//ML: The Wlan-NG drivers on the otherside fail (segfault!) if you allocate
//ML: _too much_ space. This is damn shitty crap *sigh*
//ML: We allocate a large memory region in RAM and check whether the
//ML: driver pollutes this extra space. The complaint will be made on stdout,
//ML: so please forward this...
struct iwreq wrq;
int len = sizeof( struct iw_range )*2;
char *buffer = (char*) malloc( len );
//FIXME: Validate if we actually got the memory block
@@ -885,55 +895,53 @@ OStationList* OWirelessNetworkInterface::scanNetwork()
odebug << "ONetworkInterface::scanNetwork() - scan started." << oendl;
bool results = false;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 250000; // initial timeout ~ 250ms
char buffer[IW_SCAN_MAX_DATA];
while ( !results && timeout > 0 )
{
timeout -= tv.tv_usec;
select( 0, 0, 0, 0, &tv );
_iwr.u.data.pointer = &buffer[0];
_iwr.u.data.flags = 0;
_iwr.u.data.length = sizeof buffer;
if ( wioctl( SIOCGIWSCAN ) )
{
results = true;
continue;
}
else if ( errno == EAGAIN)
{
odebug << "ONetworkInterface::scanNetwork() - scan in progress..." << oendl;
- #if 0
if ( qApp )
{
qApp->processEvents( 100 );
continue;
}
- #endif
tv.tv_sec = 0;
tv.tv_usec = 100000;
continue;
}
}
odebug << "ONetworkInterface::scanNetwork() - scan finished." << oendl;
if ( results )
{
odebug << " - result length = " << _iwr.u.data.length << oendl;
if ( !_iwr.u.data.length )
{
odebug << " - no results (empty neighbourhood)" << oendl;
return stations;
}
odebug << " - results are in!" << oendl;
dumpBytes( (const unsigned char*) &buffer[0], _iwr.u.data.length );
// parse results
struct iw_event iwe;
struct iw_stream_descr stream;
unsigned int cmd_index, event_type, event_len;
@@ -1106,63 +1114,83 @@ OStationList* OWirelessNetworkInterface::scanNetwork()
}
}
struct iw_event *we = &iwe;
//------
odebug << " - reading next event... cmd=" << we->cmd << ", len=" << we->len << oendl;
switch (we->cmd)
{
case SIOCGIWAP:
{
odebug << "SIOCGIWAP" << oendl;
stations->append( new OStation() );
stations->last()->macAddress = (const unsigned char*) &we->u.ap_addr.sa_data[0];
break;
}
case SIOCGIWMODE:
{
odebug << "SIOCGIWMODE" << oendl;
stations->last()->type = modeToString( we->u.mode );
break;
}
case SIOCGIWFREQ:
{
odebug << "SIOCGIWFREQ" << oendl;
- stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ];
+ if ( we->u.freq.m > 1000 )
+ stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ];
+ else
+ stations->last()->channel = static_cast<int>(((double) we->u.freq.m) * pow( 10.0, we->u.freq.e ));
break;
}
case SIOCGIWESSID:
{
odebug << "SIOCGIWESSID" << oendl;
we->u.essid.length = '\0'; // make sure it is zero terminated
stations->last()->ssid = static_cast<const char*> (we->u.essid.pointer);
odebug << "ESSID: " << stations->last()->ssid << oendl;
break;
}
+ case IWEVQUAL:
+ {
+ odebug << "IWEVQUAL" << oendl;
+ stations->last()->level = static_cast<int>(we->u.qual.level);
+ break; /* Quality part of statistics (scan) */
+ }
+ case SIOCGIWENCODE:
+ {
+ odebug << "SIOCGIWENCODE" << oendl;
+ stations->last()->encrypted = !(we->u.data.flags & IW_ENCODE_DISABLED);
+ break;
+ }
+
+ case SIOCGIWRATE:
+ {
+ odebug << "SIOCGIWRATE" << oendl;
+ stations->last()->rates.append(we->u.bitrate.value);
+ break;
+ }
case SIOCGIWSENS: odebug << "SIOCGIWSENS" << oendl; break;
- case SIOCGIWENCODE: odebug << "SIOCGIWENCODE" << oendl; break;
case IWEVTXDROP: odebug << "IWEVTXDROP" << oendl; break; /* Packet dropped to excessive retry */
- case IWEVQUAL: odebug << "IWEVQUAL" << oendl; break; /* Quality part of statistics (scan) */
case IWEVCUSTOM: odebug << "IWEVCUSTOM" << oendl; break; /* Driver specific ascii string */
case IWEVREGISTERED: odebug << "IWEVREGISTERED" << oendl; break; /* Discovered a new node (AP mode) */
case IWEVEXPIRED: odebug << "IWEVEXPIRED" << oendl; break; /* Expired a node (AP mode) */
default: odebug << "unhandled event" << oendl;
}
} while (true);
}
else
{
odebug << " - no results (timeout) :(" << oendl;
}
return stations;
}
int OWirelessNetworkInterface::signalStrength() const
{
iw_statistics stat;
::memset( &stat, 0, sizeof stat );
_iwr.u.data.pointer = (char*) &stat;
_iwr.u.data.flags = 0;
_iwr.u.data.length = sizeof stat;
diff --git a/libopie2/opienet/onetwork.h b/libopie2/opienet/onetwork.h
index 4d9912d..fa9f39f 100644
--- a/libopie2/opienet/onetwork.h
+++ b/libopie2/opienet/onetwork.h
@@ -392,48 +392,51 @@ class OWirelessNetworkInterface : public ONetworkInterface
virtual OChannelHopper* channelHopper() const;
/**
* Set the station @a nickname.
*/
virtual void setNickName( const QString& nickname );
/**
* @returns the current station nickname.
*/
virtual QString nickName() const;
/**
* Invoke the private IOCTL @a command with a @number of parameters on the network interface.
* @see OPrivateIOCTL
*/
virtual void setPrivate( const QString& command, int number, ... );
/**
* @returns true if the interface is featuring the private IOCTL @command.
*/
virtual bool hasPrivate( const QString& command );
virtual void getPrivate( const QString& command ); //FIXME: Implement and document this
/**
* @returns true if the interface is associated to an access point
* @note: This information is only valid if the interface is in managed mode.
*/
virtual bool isAssociated() const;
+ /** Set the @a mac associated AP address.
+ */
+ virtual void setAssociatedAP( const OMacAddress& mac ) const;
/**
* @returns the MAC address of the Access Point if the device is in infrastructure mode.
* @returns a (more or less random) cell ID address if the device is in adhoc mode.
*/
virtual OMacAddress associatedAP() const;
/**
* Set the @a ssid (Service Set ID) string. This is used to decide
* which network to associate with (use "any" to let the driver decide).
*/
virtual void setSSID( const QString& ssid );
/**
* @returns the current SSID (Service Set ID).
*/
virtual QString SSID() const;
/**
* Perform scanning the wireless network neighbourhood.
* @note: UNSTABLE API - UNDER CONSTRUCTION - DON'T USE!
*/
virtual OStationList* scanNetwork();
/**
* @return signal strength to associated neighbour (in percent).
* In infrastructure mode, this is the signal strength of the Access Point.
* In other modes the result is driver dependent.
*/
diff --git a/libopie2/opienet/ostation.h b/libopie2/opienet/ostation.h
index 5219d92..86c9a52 100644
--- a/libopie2/opienet/ostation.h
+++ b/libopie2/opienet/ostation.h
@@ -16,68 +16,70 @@
    : ..    .:,     . . . without even the implied warranty of
    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
..}^=.=       =       ; Library General Public License for more
++=   -.     .`     .: details.
 :     =  ...= . :.=-
 -.   .:....=;==+<; You should have received a copy of the GNU
  -_. . .   )=.  = Library General Public License along with
    --        :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef OSTATION_H
#define OSTATION_H
#include <opie2/onetutils.h>
#include <qlist.h>
#include <qstring.h>
#include <qhostaddress.h>
#include <qobject.h>
+#include <qvaluelist.h>
#include <sys/types.h>
namespace Opie {
namespace Net {
class OStation;
typedef QList<OStation> OStationList;
/*======================================================================================
* OStation
*======================================================================================*/
class OStation
{
public:
OStation();
~OStation();
void dump();
/* Ethernet */
QString type;
OMacAddress macAddress;
QHostAddress ipAddress;
/* WaveLan */
QString ssid;
OMacAddress apAddress;
int channel;
int level;
bool encrypted;
+ QValueList <int> rates;
private:
class Private;
Private *d;
};
}
}
#endif // OSTATION_H