author | wimpie <wimpie> | 2005-01-04 01:44:52 (UTC) |
---|---|---|
committer | wimpie <wimpie> | 2005-01-04 01:44:52 (UTC) |
commit | 9a134ab03890d942d53b4121e31e2d37859fa42c (patch) (side-by-side diff) | |
tree | e9db8bfc0734d96409c90e12712dd6d8204aeb21 /noncore | |
parent | b65cbb7c8b45d57f849722d22f8f165cc202ceb5 (diff) | |
download | opie-9a134ab03890d942d53b4121e31e2d37859fa42c.zip opie-9a134ab03890d942d53b4121e31e2d37859fa42c.tar.gz opie-9a134ab03890d942d53b4121e31e2d37859fa42c.tar.bz2 |
New bluetooth library OT2 (loosely based on kbluetooth)
18 files changed, 3483 insertions, 0 deletions
diff --git a/noncore/settings/networksettings2/opietooth2/OTManageGUI.ui b/noncore/settings/networksettings2/opietooth2/OTManageGUI.ui new file mode 100644 index 0000000..6f4db07 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTManageGUI.ui @@ -0,0 +1,198 @@ +<!DOCTYPE UI><UI> +<class>OTManageGUI</class> +<widget> + <class>QWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>OTManageGUI</cstring> + </property> + <property stdset="1"> + <name>geometry</name> + <rect> + <x>0</x> + <y>0</y> + <width>203</width> + <height>390</height> + </rect> + </property> + <property stdset="1"> + <name>caption</name> + <string>Manage local devices</string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>3</number> + </property> + <widget> + <class>QListView</class> + <column> + <property> + <name>text</name> + <string>Device</string> + </property> + <property> + <name>clickable</name> + <bool>true</bool> + </property> + <property> + <name>resizeable</name> + <bool>true</bool> + </property> + </column> + <column> + <property> + <name>text</name> + <string>New Column</string> + </property> + <property> + <name>clickable</name> + <bool>true</bool> + </property> + <property> + <name>resizeable</name> + <bool>true</bool> + </property> + </column> + <property stdset="1"> + <name>name</name> + <cstring>AllDrivers_LV</cstring> + </property> + <property stdset="1"> + <name>allColumnsShowFocus</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>rootIsDecorated</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout11</cstring> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget> + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>DriverIsUp_CB</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>Is Up</string> + </property> + </widget> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>TextLabel3</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>Auto refresh</string> + </property> + </widget> + <widget> + <class>QSpinBox</class> + <property stdset="1"> + <name>name</name> + <cstring>RefreshTimer_SB</cstring> + </property> + <property stdset="1"> + <name>maximumSize</name> + <size> + <width>60</width> + <height>32767</height> + </size> + </property> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>suffix</name> + <string>s</string> + </property> + <property stdset="1"> + <name>specialValueText</name> + <string>Default</string> + </property> + <property stdset="1"> + <name>buttonSymbols</name> + <enum>PlusMinus</enum> + </property> + <property stdset="1"> + <name>maxValue</name> + <number>10</number> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>DriverIsUp_CB</sender> + <signal>toggled(bool)</signal> + <receiver>OTManageGUI</receiver> + <slot>SLOT_UpDriver( bool)</slot> + </connection> + <connection> + <sender>RefreshTimer_SB</sender> + <signal>valueChanged(int)</signal> + <receiver>OTManageGUI</receiver> + <slot>SLOT_SetRefreshTimer( int )</slot> + </connection> + <connection> + <sender>AllDrivers_LV</sender> + <signal>currentChanged(QListViewItem*)</signal> + <receiver>OTManageGUI</receiver> + <slot>SLOT_ShowDriver( QListViewItem *)</slot> + </connection> + <connection> + <sender>AllDrivers_LV</sender> + <signal>clicked(QListViewItem*)</signal> + <receiver>OTManageGUI</receiver> + <slot>SLOT_ShowDriver( QListViewItem *)</slot> + </connection> + <slot access="public">SLOT_SetRefreshTimer( int )</slot> + <slot access="public">SLOT_ShowDriver( QListViewItem *)</slot> + <slot access="public">SLOT_UpDriver( bool)</slot> +</connections> +</UI> diff --git a/noncore/settings/networksettings2/opietooth2/OTPairingGUI.ui b/noncore/settings/networksettings2/opietooth2/OTPairingGUI.ui new file mode 100644 index 0000000..2a010f0 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTPairingGUI.ui @@ -0,0 +1,158 @@ +<!DOCTYPE UI><UI> +<class>OTPairingGUI</class> +<widget> + <class>QWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>OTPairingGUI</cstring> + </property> + <property stdset="1"> + <name>geometry</name> + <rect> + <x>0</x> + <y>0</y> + <width>285</width> + <height>230</height> + </rect> + </property> + <property stdset="1"> + <name>caption</name> + <string>Manage pairing</string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>3</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>3</number> + </property> + <widget> + <class>QListView</class> + <column> + <property> + <name>text</name> + <string>From</string> + </property> + <property> + <name>clickable</name> + <bool>true</bool> + </property> + <property> + <name>resizeable</name> + <bool>true</bool> + </property> + </column> + <column> + <property> + <name>text</name> + <string>To</string> + </property> + <property> + <name>clickable</name> + <bool>true</bool> + </property> + <property> + <name>resizeable</name> + <bool>true</bool> + </property> + </column> + <property stdset="1"> + <name>name</name> + <cstring>Pairs_LV</cstring> + </property> + <property stdset="1"> + <name>allColumnsShowFocus</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>showSortIndicator</name> + <bool>false</bool> + </property> + <property stdset="1"> + <name>rootIsDecorated</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout5</cstring> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <spacer> + <property> + <name>name</name> + <cstring>Spacer1</cstring> + </property> + <property stdset="1"> + <name>orientation</name> + <enum>Horizontal</enum> + </property> + <property stdset="1"> + <name>sizeType</name> + <enum>Expanding</enum> + </property> + <property> + <name>sizeHint</name> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>Unpair_LBL</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Disable Bluetooth to break pairings</string> + </property> + </widget> + <widget> + <class>QPushButton</class> + <property stdset="1"> + <name>name</name> + <cstring>Unpair_But</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Break</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>Unpair_But</sender> + <signal>clicked()</signal> + <receiver>OTPairingGUI</receiver> + <slot>SLOT_Unpair()</slot> + </connection> + <slot access="public">SLOT_SetRefreshTimer( int )</slot> + <slot access="public">SLOT_ShowDriver( QListViewItem *)</slot> + <slot access="public">SLOT_UpDriver( bool)</slot> + <slot access="public">SLOT_Unpair()</slot> +</connections> +</UI> diff --git a/noncore/settings/networksettings2/opietooth2/OTPeer.cpp b/noncore/settings/networksettings2/opietooth2/OTPeer.cpp new file mode 100644 index 0000000..0d7e943 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTPeer.cpp @@ -0,0 +1,366 @@ +//-*-c++-*- +/*************************************************************************** + * Copyright (C) 2003 by Fred Schaettgen * + * kdebluetooth@schaettgen.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include <assert.h> +#include <sys/poll.h> +#include <string.h> + +#include <bluezlib.h> +#include <qarray.h> +#include <qtextstream.h> + +#include <opie2/odebug.h> + +#include <OTDeviceAddress.h> +#include <OTSDPAttribute.h> +#include <OTSDPService.h> +#include <OTPeer.h> +#include <OTGateway.h> +#include <OTDriver.h> + +using namespace Opietooth2; + +OTPeer::OTPeer( OTGateway * _OT ) { + OT = _OT; + State = Peer_Unknown; + ConnectedTo = 0; +} + +OTPeer::OTPeer( QTextStream & TS, OTGateway * _OT ) { + OT = _OT; + State = Peer_Unknown; + ConnectedTo = 0; + + load( TS ); +} + +OTPeer::~OTPeer( ) { + +} + +void OTPeer::updateServices( void ) { + sdp_session_t *session; + + serviceList.clear(); + + owarn << "Get services from " << Addr.toString() << oendl; + + session = sdp_connect( &(OTDeviceAddress::any.getBDAddr()), + &(Addr.getBDAddr()), + 0); + + if (!session) { + owarn << "sdp_connect(" + << Addr.toString() + << ") failed" + << oendl; + return; // error + } + + uint32_t range = 0x0000ffff; + sdp_list_t* attrId = sdp_list_append(0, &range); + + // search all public features + uuid_t grp; + sdp_uuid16_create( &grp, PUBLIC_BROWSE_GROUP ); + sdp_list_t * search = sdp_list_append(0, &grp ); + + // get data from peer + sdp_list_t* seq; + if (sdp_service_search_attr_req( session, + search, + SDP_ATTR_REQ_RANGE, + attrId, + &seq ) ) { + owarn << "Service Search failed" << oendl; + sdp_close(session); + return; + } + + sdp_list_free(attrId, 0); + sdp_list_free(search, 0); + + // process result + sdp_list_t* next = NULL; + + for (; seq; seq = next) { + sdp_record_t *rec = (sdp_record_t *) seq->data; + + sdp_list_t* attrlist = rec->attrlist; + AttributeVector alist; + OTSDPService * service; + + service = new OTSDPService(); + + for (; attrlist; attrlist = attrlist->next) { + int attrID = ((sdp_data_t*)(attrlist->data))->attrId; + service->addAttribute( + attrID, + new OTSDPAttribute( (sdp_data_t*)(attrlist->data) ) + ); + } + + serviceList.resize( serviceList.size() + 1 ); + serviceList.insert( serviceList.size() - 1, service ); + + next = seq->next; + free(seq); + sdp_record_free(rec); + } + sdp_close(session); +} + +bool OTPeer::hasServiceClassID( const OTUUID & uuid) { + for( unsigned int i = 0; + i < serviceList.count(); + i ++ ) { + if( serviceList[i]->hasClassID(uuid)) + return true; + } + return false; +} +/** Get a vector of Rfcomm channels of the services having "uuid" in the class ID List*/ +QArray<int> OTPeer::rfcommList( const OTUUID & uuid) { + + QArray<int> rfcommList; + unsigned int channel; + + for( unsigned int i = 0; + i < serviceList.count(); + i ++ ) { + if( serviceList[i]->hasClassID(uuid)) { + if( serviceList[i]->rfcommChannel(channel) ) { + rfcommList.resize( rfcommList.size()+1 ); + rfcommList[rfcommList.size()-1] = channel; + } + } + } + return rfcommList; +} + +void OTPeer::save( QTextStream & TS ) { + TS << "bdaddr " << address().toString() << endl; + TS << "name " << name() << endl; + TS << "class " << deviceClass() << endl; +} + +void OTPeer::load( QTextStream & TS ) { + QString S; + S = TS.readLine(); + setAddress( OTDeviceAddress( S.mid( 7 ) ) ); + + S = TS.readLine(); + setName( S.mid( 5 ) ); + + S = TS.readLine(); + setDeviceClass( S.mid( 6 ).toLong() ); +} + +#define MAGICNR -99999 +#define POLLDELAY 1000 +#define PREMAGICNR (MAGICNR+POLLDELAY) + +void OTPeer::findOutState( int timeoutInSec, bool Force ) { + ProbeFD = -1; + if( Force && ConnectedTo == 0 ) { + State = OTPeer::Peer_Unknown; + } // else keep state or is connected to us + + if( State == OTPeer::Peer_Unknown ) { + ProbePhase = 0; + ProbeTimeout = timeoutInSec*1000; + owarn << "Ping " << address().toString() << oendl; + startTimer( POLLDELAY ); + } else { + ProbeTimeout = 0; + startTimer( 0 ); + } +} + +#define PINGSIZE 20 +void OTPeer::timerEvent( QTimerEvent * ev ) { + + ProbeTimeout -= POLLDELAY; + + if( State == OTPeer::Peer_Unknown ) { + switch( ProbePhase ) { + case 0 : // connect nonblock + { struct sockaddr_l2 addr; + + if (( ProbeFD = ::socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) { + ProbeTimeout = 0; + break; + } + + memset(&addr, 0, sizeof(addr)); + + addr.l2_family = AF_BLUETOOTH; + addr.l2_bdaddr = OTDeviceAddress::any.getBDAddr(); + + if( ::bind( ProbeFD, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + ProbeTimeout = 0; + break; + } + + // non blocking + if( ::fcntl( ProbeFD, F_SETFL, O_NONBLOCK ) < 0 ) { + ProbeTimeout = 0; + break; + } + + // to this peer + addr.l2_bdaddr = address().getBDAddr(); + if( ::connect( ProbeFD, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + if( errno != EAGAIN && errno != EINPROGRESS ) { + ProbeTimeout = 0; + break; + } // wait for connect to fail or succeed + } + } + ProbePhase = 1; // wait for connect + break; + case 1 : + { struct pollfd pf[1]; + char buf[L2CAP_CMD_HDR_SIZE + PINGSIZE + 20]; + int n; + + pf[0].fd = ProbeFD; + pf[0].events = POLLOUT; + if( (n = ::poll(pf, 1, 0)) < 0 ) { + owarn << address().toString() + << " : errno " + << errno + << " " + << strerror(errno)<<oendl; + ProbeTimeout = 0; + break; + } + + if( ! n ) { + // not ready -> try again + break; + } + + // send ping + for( unsigned int i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) + buf[i] = (i % 40) + 'A'; + + l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf; + + /* Build command header */ + cmd->code = L2CAP_ECHO_REQ; + cmd->ident = *(char *)this; // get some byte + cmd->len = PINGSIZE; + + /* Send Echo Request */ + if( ::send(ProbeFD, buf, PINGSIZE + L2CAP_CMD_HDR_SIZE, 0) <= 0) { + if( errno == EACCES ) { + // permission denied means that we could not + // connect because the device does not allow us + // but it is UP + owarn << address().toString() + << " good send error " + << errno + << " " + << strerror( errno) + << oendl; + State = OTPeer::Peer_Up; + ProbeTimeout = 0; + break; + } else if( errno != EBUSY ) { + owarn << address().toString() + << " : errno " + << errno + << " " + << strerror(errno) + << oendl; + ProbeTimeout = 0; + break; + } // else want some more + } + + ProbePhase = 2; // wait for ping reply + } + break; + case 2 : // wait for reply + { struct pollfd pf[1]; + char buf[L2CAP_CMD_HDR_SIZE + PINGSIZE + 20]; + l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf; + int n; + + pf[0].fd = ProbeFD; + pf[0].events = POLLIN; + if( (n = ::poll(pf, 1, 0)) < 0 ) { + owarn << address().toString() + << " : errno " + << errno + << " " + << strerror(errno) + <<oendl; + ProbeTimeout = 0; + break; + } + + if( ! n ) { + // not ready -> try again + break; + } + + if( (n = ::recv( ProbeFD, buf, sizeof(buf), 0)) < 0) { + owarn << address().toString() + << "errno " + << errno + << " " + << strerror(errno) + << oendl; + ProbeTimeout = 0; + break; + } + + /* Check for our id */ + if( cmd->ident != *(char *)this ) + // not our reply + break; + + owarn << "reply from " + << address().toString() + << oendl; + // whatever reply we get is a valid reply + State = OTPeer::Peer_Up; + ProbeTimeout = 0; + } + break; + } + + if( State != OTPeer::Peer_Unknown ) { + ProbeTimeout = 0; + } + } + + if( ProbeTimeout <= 0 ) { + // regular timeout + emit peerStateReport( this ); + if( State == Peer_Unknown ) { + State = Peer_Down; + } + if( ProbeFD >= 0 ) { + // requested to stop by caller -> stop probing + ::close( ProbeFD ); + } + // no more waiting + killTimer( ev->timerId() ); + } // else sleep some more +} + +void OTPeer::stopFindingOutState( void ) { + ProbeTimeout = PREMAGICNR; +} + diff --git a/noncore/settings/networksettings2/opietooth2/OTPeer.h b/noncore/settings/networksettings2/opietooth2/OTPeer.h new file mode 100644 index 0000000..c09af15 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTPeer.h @@ -0,0 +1,135 @@ +//-*-c++-*- +/*************************************************************************** + * Copyright (C) 2003 by Fred Schaettgen * + * kdebluetooth@0xF.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef OTPEER_H +#define OTPEER_H + +#include <qstring.h> +#include <qobject.h> +#include <qvector.h> +#include <bluezlib.h> +#include <OTDeviceAddress.h> + +class QTextStream; +class QTimerEvent; + +namespace Opietooth2 { + +class OTGateway; + +class OTDriver; +class OTSDPService; +class OTSDPAttribute; +class OTUUID; +typedef QVector<OTSDPService> ServiceVector; + +class OTPeer : public QObject { + + Q_OBJECT; + +public : + + typedef enum PeerState_E { + Peer_Unknown = -1, + Peer_Down = 0, + Peer_Up = 1 + } PeerState_t; + + OTPeer( OTGateway * _OT ); + OTPeer( QTextStream & TS, OTGateway * _TS ); + ~OTPeer(); + + inline OTGateway * gateway() const + { return OT; } + + inline int deviceClass( void ) const + { return Class; } + inline void setDeviceClass( int cls ) + { Class = cls; } + + void setAddress( const OTDeviceAddress & A ) + { Addr = A; } + + const OTDeviceAddress & address( void ) + { return Addr; } + + inline QString name( void ) const + { return Name; } + inline void setName( const QString & n ) + { Name = n; } + + ServiceVector & services( bool Force = 0 ) + { if( Force || serviceList.count() == 0 ) { + updateServices(); + } + return serviceList; + } + + /* Returns TRUE if the device has at least a service + with inside the required class Id.*/ + bool hasServiceClassID( const OTUUID & uuid); + + /* Get a vector of Rfcomm channels of the services + having "uuid" in the class ID List */ + QArray<int> rfcommList( const OTUUID & uuid ); + + inline void setState( PeerState_t S) + { State = S; } + inline PeerState_t state( void ) + { return State; } + + // go and find out state + // will report back with signal + void findOutState( int timeoutInSec = 1, bool Force = 0 ); + void stopFindingOutState( void ); + + // return driver to which this peer is connected to + // if it is connected + inline OTDriver * connectedTo( void ) const + { return ConnectedTo; } + inline void setConnectedTo( OTDriver * D ) + { ConnectedTo = D; } + + void save( QTextStream& TS ); + void load( QTextStream& TS ); + +signals : + + // report back state + void peerStateReport( OTPeer *); + void error( const QString & ); + +protected : + + // while polling for result of ping + void timerEvent( QTimerEvent * ev ); + +private: + + void updateServices(); + + OTGateway * OT; + OTDeviceAddress Addr; + QString Name; + int Class; + ServiceVector serviceList; + // -1 : don't know, 0 no, 1 yes + PeerState_t State; + OTDriver * ConnectedTo; + + int ProbeFD; + int ProbePhase; // see OTDriver + long ProbeTimeout; +}; + +} + +#endif diff --git a/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp b/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp new file mode 100644 index 0000000..9069c09 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp @@ -0,0 +1,329 @@ +//-*-c++-*- +/*************************************************************************** + * Copyright (C) 2003 by Fred Schaettgen * + * kdebluetooth@schaettgen.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include <assert.h> +#include <qregexp.h> +#include <opie2/odebug.h> + +#include <OTUUID.h> +#include <OTSDPAttribute.h> + +using namespace Opietooth2; + +OTSDPAttribute::OTSDPAttribute() { + type = INVALID; + memset( &Value, 0, sizeof( Value ) ); +} + +OTSDPAttribute::~OTSDPAttribute() { + if( type == INT ) { + delete Value.intVal; + } else if( type == UUID ) { + delete Value.uuidVal; + } else if( type == UINT ) { + delete Value.uintVal; + } else if( type == STRING || + type == URL + ) { + delete Value.stringVal; + } else if( type == ALTERNATIVE || + type == SEQUENCE + ) { + delete Value.sequenceVal; + } +} + +OTSDPAttribute::OTSDPAttribute( sdp_data_t * attrib ) { + setNil(); + switch( attrib->dtd ) { + case SDP_DATA_NIL: // Nil type + { setNil(); + break; + } + case SDP_UINT8: // Unsigned integer + setUInt(attrib->val.uint8); + break; + case SDP_UINT16: // Unsigned integer + setUInt(attrib->val.uint16); + break; + case SDP_UINT32: // Unsigned integer + setUInt(attrib->val.uint32); + break; + case SDP_UINT64: // Unsigned integer + setUInt(attrib->val.uint64); + break; + case SDP_UINT128: // Unsigned integer + // setUInt(attrib->val.uint16); + assert(false); // BUG/TODO: uint128 integers not supported + break; + case SDP_INT8: // Unsigned integer + setInt(attrib->val.int8); + break; + case SDP_INT16: // Unsigned integer + setInt(attrib->val.int16); + break; + case SDP_INT32: // Unsigned integer + setInt(attrib->val.int32); + break; + case SDP_INT64: // Unsigned integer + setInt(attrib->val.int64); + break; + case SDP_INT128: // Unsigned integer + // newAttr.setInt(attrib->val.uint16); + assert(false); // BUG/TODO: uint128 integers not supported + break; + case SDP_UUID16: + { OTUUID id; + ::uuid_t uuidVal = attrib->val.uuid; + id.setUUID32(uuidVal.value.uuid16); + setUUID(id ); + } + break; + case SDP_UUID32: + { OTUUID id; + ::uuid_t uuidVal = attrib->val.uuid; + id.setUUID32(uuidVal.value.uuid32); + setUUID(id ); + } + break; + case SDP_UUID128: + { OTUUID id; + ::uuid_t uuidVal = attrib->val.uuid; + uint64_t* v128; + v128 = reinterpret_cast<uint64_t*>(&(uuidVal.value.uuid128)); + id.setUUID128(v128[0], v128[1]); + setUUID(id ); + } + break; + case SDP_TEXT_STR_UNSPEC : + case SDP_TEXT_STR8 : + case SDP_TEXT_STR16 : + case SDP_TEXT_STR32 : + setString( QString(attrib->val.str) ); + break; + case SDP_URL_STR_UNSPEC : + case SDP_URL_STR8 : + case SDP_URL_STR16 : + case SDP_URL_STR32 : + setURL( QString(attrib->val.str) ); + break; + case SDP_BOOL: + setBool( attrib->val.int8 != 0); + break; + case SDP_SEQ_UNSPEC : + case SDP_SEQ8 : + case SDP_SEQ16 : + case SDP_SEQ32 : + case SDP_ALT_UNSPEC : + case SDP_ALT8 : + case SDP_ALT16 : + case SDP_ALT32 : + { AttributeVector subAttribs; + OTSDPAttribute * Attr; + sdp_data_t* subAttrib = attrib->val.dataseq; + + for (; subAttrib; subAttrib = subAttrib->next) { + + Attr = new OTSDPAttribute(subAttrib); + subAttribs.resize( subAttribs.size() + 1 ); + subAttribs.insert( subAttribs.size() - 1, Attr ); + } + + if( attrib->dtd == SDP_ALT_UNSPEC || + attrib->dtd == SDP_ALT8 || + attrib->dtd == SDP_ALT16 || + attrib->dtd == SDP_ALT32 ) { + setAlternative(subAttribs); + } else { + setSequence(subAttribs); + } + break; + } + } // end case +} + +QString OTSDPAttribute::toString( void ) { + QString S; + switch( type ) { + case INVALID : + S = "invalid"; + break; + case NIL : + S = "NIL"; + break; + case UINT : + S = Value.uintVal->toString(); + break; + case INT : + S = Value.intVal->toString(); + break; + case UUID : + S = Value.uuidVal->toString(); + break; + case BOOLEAN : + S = (Value.boolVal) ? "true" : "false"; + break; + case STRING : + S = *(Value.stringVal); + break; + case URL : + S = *(Value.stringVal); + break; + case SEQUENCE : + S.sprintf( "Sequence(%d)", Value.sequenceVal->count() ); + break; + case ALTERNATIVE : + S.sprintf( "Alternative(%d)", Value.sequenceVal->count() ); + break; + case UNKNOWN : + S = "unknown"; + break; + } + return S; +} + +void OTSDPAttribute::setNil() { + type = NIL; +} + +void OTSDPAttribute::setInt(const OTSDPAttribute::int128_t & val) { + type = INT; + Value.intVal = new int128_t( val ); +} + +void OTSDPAttribute::setUInt(const uint128_t & val) { + type = UINT; + Value.uintVal = new uint128_t(val); +} + +void OTSDPAttribute::setUUID(const OTUUID & val) { + type = UUID; + Value.uuidVal = new OTUUID( val ); +} + +void OTSDPAttribute::setBool(bool val) { + type = BOOLEAN; + Value.boolVal = val; +} + +void OTSDPAttribute::setString( const QString & val) { + type = STRING; + Value.stringVal = new QString( val ); +} + +void OTSDPAttribute::setURL( const QString & val) { + type = URL; + Value.stringVal = new QString(val); +} + +void OTSDPAttribute::setSequence(const AttributeVector& val) { + type = SEQUENCE; + Value.sequenceVal = new AttributeVector(); + Value.sequenceVal->setAutoDelete( TRUE ); + *Value.sequenceVal = val; +} + +void OTSDPAttribute::setAlternative(const AttributeVector& val) { + type = ALTERNATIVE; + Value.sequenceVal = new AttributeVector(); + Value.sequenceVal->setAutoDelete( TRUE ); + *Value.sequenceVal = val; +} + +QString OTSDPAttribute::getString() { + assert(type == STRING); + return *Value.stringVal; +} + +QString OTSDPAttribute::getURL() { + assert(type == URL); + return *Value.stringVal; +} + +const OTSDPAttribute::int128_t & OTSDPAttribute::getInt() { + assert(type == INT); + return *Value.intVal; +} + + +const OTSDPAttribute::uint128_t & OTSDPAttribute::getUInt() { + assert(type == UINT); + return *Value.uintVal; +} + +const OTUUID & OTSDPAttribute::getUUID() { + assert(type == UUID); + return *Value.uuidVal; +} + +bool OTSDPAttribute::getBool() { + assert(type == BOOLEAN); + return Value.boolVal; +} + +AttributeVector * OTSDPAttribute::getSequence() { + assert(type == SEQUENCE); + return Value.sequenceVal; +} + +AttributeVector * OTSDPAttribute::getAlternative() { + assert(type == ALTERNATIVE); + return Value.sequenceVal; +} + +UUIDVector OTSDPAttribute::getAllUUIDs() { + + UUIDVector uuids; + + if (getType() == UUID) { + uuids.resize( uuids.size()+1 ); + uuids[uuids.size()-1] = getUUID(); + } else { + AttributeVector * subAttributes = 0 ; + + if (getType() == SEQUENCE) { + subAttributes = getSequence(); + } else if (getType() == ALTERNATIVE) { + subAttributes = getAlternative(); + } + + int os; + for( unsigned int i = 0; i < subAttributes->count(); i++ ) { + UUIDVector subUUIDs = (*subAttributes)[i]->getAllUUIDs(); + + os = uuids.size(); + uuids.resize( uuids.size()+subUUIDs.count() ); + + for( unsigned int k = 0; k < subUUIDs.count(); k++ ) { + uuids[os + k] = subUUIDs[k]; + } + } + } + return uuids; +} + +static char * Attr2String[] = { + "Invalid", + "Nil", + "UInt", + "int", + "UUID", + "Boolean", + "String", + "Sequence", + "Alternative", + "URL", + "Unknown" +}; + +const char * OTSDPAttribute::getTypeString() { + return Attr2String[type]; +} diff --git a/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.h b/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.h new file mode 100644 index 0000000..e79e33d --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.h @@ -0,0 +1,140 @@ +//-*-c++-*- +/*************************************************************************** + * Copyright (C) 2003 by Fred Schaettgen * + * kdebluetooth@schaettgen.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef OTATTRIBUTE_H +#define OTATTRIBUTE_H + +#include <stdio.h> +#include <qstring.h> +#include <qarray.h> +#include <qvector.h> +#include <bluezlib.h> +#include <OTUUID.h> + +namespace Opietooth2 { + +class OTSDPAttribute; +class OTUUID; + +typedef QVector<OTSDPAttribute> AttributeVector; + +/** +@author Fred Schaettgen +*/ +class OTSDPAttribute { + +public: + + enum AttrType { + INVALID = 0, + NIL = 1, + UINT = 2, + INT = 3, + UUID = 4, + BOOLEAN = 5, + STRING = 6, + SEQUENCE = 7, + ALTERNATIVE = 8, + URL = 9, + UNKNOWN = 10 + }; + + class int128_t { + public : + int128_t(int64_t l=0, int64_t h=0) { + hi = h; + lo = l; + } + int128_t(const OTSDPAttribute::int128_t & l) { + hi = l.hi; + lo = l.lo; + } + QString toString() const { + char Buf[50]; + sprintf( Buf, "%lld%lld", hi, lo ); + return QString( Buf ); + } + int64_t hi; + int64_t lo; + }; + + class uint128_t { + public : + uint128_t( uint64_t l=0, uint64_t h=0) { + hi = h; + lo = l; + } + uint128_t( const OTSDPAttribute::uint128_t & l) { + hi = l.hi; + lo = l.lo; + } + QString toString() const { + char Buf[50]; + sprintf( Buf, "%llu%llu", hi, lo ); + return QString( Buf ); + } + uint64_t hi; + uint64_t lo; + }; + +public: + + OTSDPAttribute(); + OTSDPAttribute( sdp_data_t * D ); + ~OTSDPAttribute(); + + QString toString( void ); + + void setNil(); + void setInt(const OTSDPAttribute::int128_t & val); + void setUInt(const OTSDPAttribute::uint128_t & val); + void setUUID( const OTUUID & val); + void setBool(bool val); + void setString(const QString & val); + void setURL(const QString & val); + void setSequence(const AttributeVector& val); + void setAlternative(const AttributeVector& val); + + QString getString(); + QString getURL(); + const OTSDPAttribute::int128_t & getInt(); + const OTSDPAttribute::uint128_t & getUInt(); + const OTUUID & getUUID(); + bool getBool(); + AttributeVector * getSequence(); + AttributeVector * getAlternative(); + + UUIDVector getAllUUIDs(); + + inline AttrType getType() + { return type; } + + //QString getValString(); + const char * getTypeString(); + +private: + + AttrType type; + + union { + OTSDPAttribute::int128_t * intVal; + OTSDPAttribute::uint128_t * uintVal; + OTUUID * uuidVal; + bool boolVal; + QString * stringVal; // strings and urls + AttributeVector * sequenceVal; // sequences and alternatives + } Value; + +}; + +} + +#endif diff --git a/noncore/settings/networksettings2/opietooth2/OTSDPService.cpp b/noncore/settings/networksettings2/opietooth2/OTSDPService.cpp new file mode 100644 index 0000000..07b505c --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTSDPService.cpp @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright (C) 2003 by Fred Schaettgen * + * kdebluetooth@schaettgen.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include <opie2/odebug.h> + +#include <OTSDPAttribute.h> +#include <OTSDPService.h> + +using namespace Opietooth2; + +OTSDPService::OTSDPService() : attributeList() { +} + +OTSDPService::~OTSDPService() { + for (unsigned int n=0; n < attributeList.count(); ++n) { + delete attributeList[n].attr; + } +} + +void OTSDPService::addAttribute(int id, OTSDPAttribute * attr) { + attributeList.resize( attributeList.size() + 1 ); + + attributeList[attributeList.size() - 1].id = id; + attributeList[attributeList.size() - 1].attr = attr; +} + +const OTSDPAttribute & OTSDPService::attribute(int index) { + return *(attributeList[index].attr); +} + +int OTSDPService::attributeID(int index) { + return attributeList[index].id; + +} + +OTSDPAttribute * OTSDPService::attributeByID(int id) { + + for (unsigned int n=0; n < attributeList.count(); ++n) { + if (attributeList[n].id == id) { + return attributeList[n].attr; + } + } + return 0; +} + +bool OTSDPService::recordHandle(uint32_t *handle) { + OTSDPAttribute * attrib; + attrib = attributeByID(0x00); + if( attrib && attrib->getType() == OTSDPAttribute::UINT) { + *handle = (uint32_t)attrib->getUInt().lo; + return true; + } + return false; +} + +QString OTSDPService::name(void) { + QString S; + OTSDPAttribute * attrib; + attrib = attributeByID(0x100); + if( attrib && attrib->getType() == OTSDPAttribute::STRING) { + S = attrib->getString(); + } + return S; +} + +QString OTSDPService::description() { + QString S; + OTSDPAttribute * attrib; + attrib = attributeByID(0x101); + if ( attrib && attrib->getType() == OTSDPAttribute::STRING) { + S = attrib->getString(); + } + return S; +} + +UUIDVector OTSDPService::allUUIDs() { + UUIDVector uuidList; + + for ( unsigned int i = 0; + i < attributeList.count(); + i ++ ) { + int os; + UUIDVector subList = attributeList[i].attr->getAllUUIDs(); + os = uuidList.size(); + uuidList.resize( uuidList.size()+subList.count() ); + + for( unsigned int k = 0; k < subList.count(); k++ ) { + uuidList[os + k] = subList[k]; + } + } + return uuidList; +} + +bool OTSDPService::rfcommChannel(unsigned int &n) { + // Get the rfcomm channel + OTSDPAttribute * protoDescAttr; + // Get the the protocol descriptor list attribute (0x04) + protoDescAttr = attributeByID(0x04); + if( ! protoDescAttr ) { + return false; + } + + AttributeVector & protoDescList = *(protoDescAttr->getSequence()); + + for( unsigned int i = 0; + i < protoDescList.count(); + i ++ ) { + AttributeVector & attrList = *(protoDescList[i]->getSequence()); + + //The List must have at least 2 Attributes + //Example: + // UUID16 : 0x0003 - RFCOMM + // Channel/Port (Integer) : 0x6 + if(attrList.size() >= 2) { + // The first Attribute of the list must be an UUID + if( attrList[0]->getType() != OTSDPAttribute::UUID) + continue; + // The UUID must have the value of "0x0003" that's the RFCOMM UUID + OTUUID rfcommUUID( "0x0003" ); + if( attrList[0]->getUUID() != rfcommUUID) //RFCOMM UUID + continue; + //If the UUID is ok we get the rfcomm channel number + if( attrList[1]->getType() != OTSDPAttribute::UINT) + continue; + + n = attrList[1]->getUInt().lo; + + return true; + } + } + // If we're here, we haven't found a correct Rfcomm channel, so we return false + return false; +} + +bool OTSDPService::hasClassID(const OTUUID & uuid) { + OTSDPAttribute * ClassIDAttr; + + // Get the the ClassID descriptor list attribute (0x01) + ClassIDAttr = attributeByID( 0x01); + if( ! ClassIDAttr ) { + return false; + } + + AttributeVector & ClassIDList = *(ClassIDAttr->getSequence()); + for( unsigned int i = 0 ; + i < ClassIDList.count() ; + i ++ ) { + if( ClassIDList[i]->getType() != OTSDPAttribute::UUID) + continue; + if( ClassIDList[i]->getUUID() == uuid) + return true; + } + return false; +} + +/** Get a vector of UUID of the services class Id List */ +UUIDVector OTSDPService::classIDList( void ) { + + UUIDVector uuidList; + OTSDPAttribute * ClassIDAttr; + + // Get the the ClassID descriptor list attribute (0x01) + ClassIDAttr = attributeByID( 0x01); + if( ! ClassIDAttr ) { + return uuidList; + } + + AttributeVector & ClassIDList = *(ClassIDAttr->getSequence()); + + for( unsigned int i = 0 ; + i < ClassIDList.count() ; + i ++ ) { + if( ClassIDList[i]->getType() != OTSDPAttribute::UUID) + continue; + + uuidList.resize( uuidList.size() + 1 ); + uuidList[ uuidList.size() - 1 ] = ClassIDList[i]->getUUID(); + } + + return uuidList; +} + diff --git a/noncore/settings/networksettings2/opietooth2/OTSDPService.h b/noncore/settings/networksettings2/opietooth2/OTSDPService.h new file mode 100644 index 0000000..4831df0 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTSDPService.h @@ -0,0 +1,75 @@ +//-*-c++-*- +/*************************************************************************** + * Copyright (C) 2003 by Fred Schaettgen * + * kdebluetooth@schaettgen.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef SDPSERVICE_H +#define SDPSERVICE_H + +#include <qvector.h> +#include <qarray.h> +#include <OTSDPAttribute.h> + +namespace Opietooth2 { + +/** +@author Fred Schaettgen +*/ +class OTSDPService { + +public: + + OTSDPService(); + virtual ~OTSDPService(); + + void addAttribute(int id, OTSDPAttribute * attr); + + const OTSDPAttribute & attribute( int index ); + int attributeID( int index ); + + AttributeVector subAttributes( OTSDPAttribute * attr); + OTSDPAttribute * attributeByID( int id ); + + // See Bluetooth Core Spec Sec. 5.1 + bool recordHandle(uint32_t *handle); // 0x00 + + //bool getServiceClassIDList(vector<uuid_t> *classIDList); // 0x01 + //bool getServiceRecordState(uint32_t *state); // 0x02 + //bool getServiceID(uuid_t *id); // 0x03; + //bool getProtocolDescriptorList(SDP::Attribute *attribute); // 0x04 + //bool getBrowseGroupList(vector<uuid_t> *browseGroupList); // 0x05 + QString name(void); // langBase + 0x00 + QString description(void); // langBase + 0x01 + + UUIDVector allUUIDs(); + + // return list of classes this service belongs to + UUIDVector classIDList(); + + /** Retrieves the Rfcomm channel. + This function is provided just for conveniance. + @param n The Rfcomm channel. + @ret true if an rfcomm channel was found, false otherwise. */ + bool rfcommChannel(unsigned int &n); + + bool hasClassID(const OTUUID & uuid); + +private: + + struct AttributeEntry { + int id; + OTSDPAttribute * attr; + }; + + QArray<AttributeEntry> attributeList; +}; + +} + +#endif diff --git a/noncore/settings/networksettings2/opietooth2/OTScanGUI.ui b/noncore/settings/networksettings2/opietooth2/OTScanGUI.ui new file mode 100644 index 0000000..66c19e6 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTScanGUI.ui @@ -0,0 +1,387 @@ +<!DOCTYPE UI><UI> +<class>OTScanGUI</class> +<widget> + <class>QWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Form3</cstring> + </property> + <property stdset="1"> + <name>geometry</name> + <rect> + <x>0</x> + <y>0</y> + <width>333</width> + <height>580</height> + </rect> + </property> + <property stdset="1"> + <name>caption</name> + <string>Scanning</string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>3</number> + </property> + <widget> + <class>QListView</class> + <column> + <property> + <name>text</name> + <string>Attribute</string> + </property> + <property> + <name>clickable</name> + <bool>true</bool> + </property> + <property> + <name>resizeable</name> + <bool>true</bool> + </property> + </column> + <column> + <property> + <name>text</name> + <string>Value</string> + </property> + <property> + <name>clickable</name> + <bool>true</bool> + </property> + <property> + <name>resizeable</name> + <bool>true</bool> + </property> + </column> + <property stdset="1"> + <name>name</name> + <cstring>DetectedPeers_LV</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>allColumnsShowFocus</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>rootIsDecorated</name> + <bool>true</bool> + </property> + </widget> + <widget> + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout16</cstring> + </property> + <property> + <name>layoutSpacing</name> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>3</number> + </property> + <widget> + <class>QPushButton</class> + <property stdset="1"> + <name>name</name> + <cstring>Cleanup_But</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Cleanup</string> + </property> + </widget> + <spacer> + <property> + <name>name</name> + <cstring>Spacer1</cstring> + </property> + <property stdset="1"> + <name>orientation</name> + <enum>Horizontal</enum> + </property> + <property stdset="1"> + <name>sizeType</name> + <enum>Expanding</enum> + </property> + <property> + <name>sizeHint</name> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget> + <class>QPushButton</class> + <property stdset="1"> + <name>name</name> + <cstring>Detect_But</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>Scan</string> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>autoResize</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>toggleButton</name> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget> + <class>QGroupBox</class> + <property stdset="1"> + <name>name</name> + <cstring>Peer_GB</cstring> + </property> + <property stdset="1"> + <name>title</name> + <string>GroupBox1</string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <grid> + <property stdset="1"> + <name>margin</name> + <number>3</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>3</number> + </property> + <widget row="2" column="0" rowspan="1" colspan="2" > + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout4</cstring> + </property> + <hbox> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget> + <class>QFrame</class> + <property stdset="1"> + <name>name</name> + <cstring>State_Frm</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>frameShape</name> + <enum>NoFrame</enum> + </property> + <property stdset="1"> + <name>frameShadow</name> + <enum>Raised</enum> + </property> + </widget> + <widget> + <class>QPushButton</class> + <property stdset="1"> + <name>name</name> + <cstring>RefreshServices_But</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Services</string> + </property> + </widget> + <widget> + <class>QPushButton</class> + <property stdset="1"> + <name>name</name> + <cstring>RefreshState_But</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>State</string> + </property> + </widget> + </hbox> + </widget> + <widget row="0" column="1" > + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>Address_LBL</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>frameShape</name> + <enum>Panel</enum> + </property> + <property stdset="1"> + <name>frameShadow</name> + <enum>Plain</enum> + </property> + <property stdset="1"> + <name>lineWidth</name> + <number>1</number> + </property> + <property stdset="1"> + <name>text</name> + <string></string> + </property> + <property stdset="1"> + <name>indent</name> + <number>1</number> + </property> + </widget> + <widget row="0" column="0" > + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>TextLabel1</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>text</name> + <string>Address</string> + </property> + </widget> + <widget row="1" column="0" > + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>TextLabel2</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Signal strength</string> + </property> + </widget> + <widget row="1" column="1" > + <class>QProgressBar</class> + <property stdset="1"> + <name>name</name> + <cstring>Strength_PB</cstring> + </property> + <property stdset="1"> + <name>centerIndicator</name> + <bool>true</bool> + </property> + <property stdset="1"> + <name>indicatorFollowsStyle</name> + <bool>false</bool> + </property> + </widget> + </grid> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>RefreshServices_But</sender> + <signal>clicked()</signal> + <receiver>Form3</receiver> + <slot>SLOT_RefreshServices()</slot> + </connection> + <connection> + <sender>Detect_But</sender> + <signal>toggled(bool)</signal> + <receiver>Form3</receiver> + <slot>SLOT_DoScan( bool )</slot> + </connection> + <connection> + <sender>Cleanup_But</sender> + <signal>clicked()</signal> + <receiver>Form3</receiver> + <slot>SLOT_CleanupOld()</slot> + </connection> + <connection> + <sender>RefreshState_But</sender> + <signal>clicked()</signal> + <receiver>Form3</receiver> + <slot>SLOT_RefreshState()</slot> + </connection> + <connection> + <sender>DetectedPeers_LV</sender> + <signal>clicked(QListViewItem*)</signal> + <receiver>Form3</receiver> + <slot>SLOT_Show(QListViewItem *)</slot> + </connection> + <connection> + <sender>DetectedPeers_LV</sender> + <signal>currentChanged(QListViewItem*)</signal> + <receiver>Form3</receiver> + <slot>SLOT_Show(QListViewItem *)</slot> + </connection> + <connection> + <sender>DetectedPeers_LV</sender> + <signal>doubleClicked(QListViewItem*)</signal> + <receiver>Form3</receiver> + <slot>SLOT_Selected(QListViewItem*)</slot> + </connection> + <slot access="public">SLOT_CleanupOld()</slot> + <slot access="public">SLOT_DoScan( bool )</slot> + <slot access="public">SLOT_RefreshServices()</slot> + <slot access="public">SLOT_RefreshState()</slot> + <slot access="public">SLOT_Selected(QListViewItem*)</slot> + <slot access="public">SLOT_Show(QListViewItem *)</slot> +</connections> +</UI> diff --git a/noncore/settings/networksettings2/opietooth2/OTUUID.cpp b/noncore/settings/networksettings2/opietooth2/OTUUID.cpp new file mode 100644 index 0000000..4b05a7a --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTUUID.cpp @@ -0,0 +1,162 @@ +//-*-c++-*- +/*************************************************************************** + * Copyright (C) 2003 by Fred Schaettgen * + * kdebluetooth@schaettgen.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include <assert.h> +#include <qregexp.h> +#include <opie2/odebug.h> + +#include <OTUUID.h> + +using namespace Opietooth2; + +OTUUID::OTUUID(QString s) { + fromString(s); +} + +OTUUID::OTUUID(uint64_t l, uint64_t h) { + this->hi = h; + this->lo = l; +} + +OTUUID::OTUUID( const OTUUID & O ) { + this->hi = O.hi; + this->lo = O.lo; +} + +OTUUID & OTUUID::operator =( const OTUUID & O ) { + hi = O.hi; + lo = O.lo; + return *this; +} + +bool OTUUID::fromString(QString s) { + + // Strip leading "0x" + if (s.startsWith("0x")) + { + s = s.right(s.length()-2); + } + // Remove separators + s.replace( QRegExp(":"), "" ); + + bool bOk = false; + if( s.length() == 4 || s.length() == 8) { + + uint32_t u32 = s.toUInt(&bOk, 16); + setUUID32(u32); + return bOk; + + } else if (s.length() == 32) { + +#if (QT_VERSION >= 0x030200) + uint64_t u64hi = s.left(16).toULongLong(&bOk, 16); +#else + uint64_t u64hi = s.left(16).toULong(&bOk, 16); +#endif + if (!bOk) + return false; + +#if (QT_VERSION >= 0x030200) + uint64_t u64lo = s.right(16).toULongLong(&bOk, 16); +#else + uint64_t u64lo = s.right(16).toULong(&bOk, 16); +#endif + if (!bOk) + return false; + hi = u64hi; + lo = u64lo; + return true; + + } else { + hi = 0; + lo = 0; + return true; + } +} + +void OTUUID::setUUID32(uint32_t v) { + + hi = uint64_t(0x1000) | (uint64_t(v) << 32); + // see BT 1.1 Core spec p2.7.1 + lo = (uint64_t(0x80000080) << 32) | uint64_t(0x5F9B34FB); + +} + +void OTUUID::setUUID128(uint64_t _hi, uint64_t _lo) { + hi = _hi; + lo = _lo; +} + +QString OTUUID::toString() const { + QString ret; + uint32_t v1 = uint32_t(hi >> 32); + uint32_t v2 = uint32_t(hi & 0xFFFFFFFF); + uint32_t v3 = uint32_t(lo >> 32); + uint32_t v4 = uint32_t(lo & 0xFFFFFFFF); + ret.sprintf("0x%08lx:%08lx:%08lx:%08lx", + (unsigned long)v1, (unsigned long)v2, + (unsigned long)v3, (unsigned long)v4); + + return ret; +} + +OTUUID::operator QString() const { + return toString(); +} + +OTUUID::operator ::uuid_t() const { + + //kdDebug() << "uuid_t() -> " << QString(*this) << endl; + ::uuid_t ret; + if ((lo == (uint64_t(0x80000080) << 32) | uint64_t(0x5F9B34FB)) && + ((hi&0xFFFFFFFF) == 0x1000)) { + uint32_t uuid32val = uint32_t(hi >> 32); + if (uuid32val > 0xFFFF) { + ret.type = SDP_UUID16; + ret.value.uuid16 = uint16_t(uuid32val); + } else { + ret.type = SDP_UUID32; + ret.value.uuid32 = uuid32val; + } + } else { + ret.value.uuid128.data[0] = (lo >> 0) && 0xFF; + ret.value.uuid128.data[1] = (lo >> 8) && 0xFF; + ret.value.uuid128.data[2] = (lo >> 16) && 0xFF; + ret.value.uuid128.data[3] = (lo >> 24) && 0xFF; + ret.value.uuid128.data[4] = (lo >> 32) && 0xFF; + ret.value.uuid128.data[5] = (lo >> 40) && 0xFF; + ret.value.uuid128.data[6] = (lo >> 48) && 0xFF; + ret.value.uuid128.data[7] = (lo >> 56) && 0xFF; + + ret.value.uuid128.data[8] = (hi >> 0) && 0xFF; + ret.value.uuid128.data[9] = (hi >> 8) && 0xFF; + ret.value.uuid128.data[10] = (hi >> 16) && 0xFF; + ret.value.uuid128.data[11] = (hi >> 24) && 0xFF; + ret.value.uuid128.data[12] = (hi >> 32) && 0xFF; + ret.value.uuid128.data[13] = (hi >> 40) && 0xFF; + ret.value.uuid128.data[14] = (hi >> 48) && 0xFF; + ret.value.uuid128.data[15] = (hi >> 56) && 0xFF; + + ret.type = SDP_UUID128; + } + return ret; +} + +bool OTUUID::operator<(const OTUUID & other) const { + if (hi != other.hi) + return hi < other.hi; + + return lo<other.lo; +} + +bool OTUUID::operator ==(const OTUUID& u) const { + return (u.hi == hi) && (u.lo == lo); +} diff --git a/noncore/settings/networksettings2/opietooth2/OTUUID.h b/noncore/settings/networksettings2/opietooth2/OTUUID.h new file mode 100644 index 0000000..aebd9b9 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/OTUUID.h @@ -0,0 +1,58 @@ +//-*-c++-*- +/*************************************************************************** + * Copyright (C) 2003 by Fred Schaettgen * + * kdebluetooth@schaettgen.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef OTUUID_H +#define OTUUID_H + +#include <qstring.h> +#include <qarray.h> +#include <bluezlib.h> + +namespace Opietooth2 { + +class OTUUID; + +typedef QArray<OTUUID> UUIDVector; + +class OTUUID { + +public : + + OTUUID( QString s ); + OTUUID( uint64_t l=0, uint64_t h=0); + OTUUID( const OTUUID & O ); + + bool fromString(QString s); + + void setUUID128(uint64_t hi, uint64_t lo); + + void setUUID32(uint32_t v); + + uint16_t toShort() + { return ((hi>>32) & 0xffff); } + uint32_t toLong() + { return ((hi>>32) & 0xffffffff); } + uint64_t toLongLong() + { return hi; } + + QString toString() const ; + operator QString() const; + operator ::uuid_t() const; + + OTUUID & operator=( const OTUUID & other ) ; + bool operator<( const OTUUID & other ) const; + bool operator==(const OTUUID & uuid) const; + + uint64_t hi; + uint64_t lo; +}; +} +#endif diff --git a/noncore/settings/networksettings2/opietooth2/Opietooth.cpp b/noncore/settings/networksettings2/opietooth2/Opietooth.cpp new file mode 100644 index 0000000..8d71f32 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/Opietooth.cpp @@ -0,0 +1,1003 @@ +#include <opie2/odebug.h> +#include <opie2/oledbox.h> + +#include <qpe/resource.h> +#include <qcheckbox.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qprogressbar.h> +#include <qheader.h> +#include <qmessagebox.h> +#include <qapplication.h> +#include <qlistbox.h> +#include <qdialog.h> +#include <qlayout.h> +#include <qcombobox.h> +#include <qlabel.h> +#include <qlistview.h> +#include <qpushbutton.h> + +#include <Opietooth.h> +#include <OTDriver.h> +#include <OTPeer.h> +#include <OTGateway.h> +#include <OTSDPAttribute.h> +#include <OTSDPService.h> +#include <OTInquiry.h> + +using namespace Opietooth2; + +namespace Opietooth2 { + +class PeerLVI : public QListViewItem { + +public : + + PeerLVI( OTPeer * P, QListView * it ) : QListViewItem (it) { + Peer = P; + } + ~PeerLVI( void ) { + } + + inline OTPeer * peer( void ) + { return Peer; } + +private : + + OTPeer * Peer; +}; + +class ChannelLVI : public QListViewItem { + +public : + + ChannelLVI( int Ch, QListViewItem * it ) : QListViewItem (it) { + Channel = Ch; + } + ~ChannelLVI( void ) { + } + + inline int channel( void ) + { return Channel; } + +private : + + int Channel; +}; + +class DriverLVI : public QListViewItem { + +public : + + DriverLVI( OTDriver * P, QListView * it ) : QListViewItem (it) { + Driver = P; + } + ~DriverLVI( void ) { + } + + inline OTDriver * driver( void ) + { return Driver; } + +private : + + OTDriver * Driver; +}; + +class LinkKeyLVI : public QListViewItem { + +public : + + LinkKeyLVI( int Ch, QListView * it ) : QListViewItem (it) { + LinkKey = Ch; + } + ~LinkKeyLVI( void ) { + } + + inline int index( void ) + { return LinkKey; } + +private : + + int LinkKey; +}; +}; + +// +// +// +// +// + +OTPairing::OTPairing( QWidget * parent, OTIcons * _IC ) : + OTPairingGUI( parent ) { + + OT = OTGateway::getOTGateway(); + Icons = (_IC ) ? _IC : new OTIcons(); + MyIcons = (_IC == 0 ); + + // unpairing can only be done if bluetooth is disabled + Unpair_But->setEnabled( ! OT->isEnabled() ); + if( ! OT->isEnabled() ) { + Unpair_LBL->hide(); + } else { + Unpair_LBL->show(); + } + + // open linkkey file and load pairs + LinkKeyArray Keys = OT->getLinkKeys(); + LinkKeyLVI * it; + OTPeer * P; + OTDriver * D; + + for( unsigned int i = 0 ; + i < Keys.count(); + i ++ ) { + + it = new LinkKeyLVI( i, Pairs_LV ); + + P = 0; + D = OT->findDriver( Keys[i].from() ); + + if( D ) { + it->setText( 0, D->devname() ); + + // we are source + P = OT->findPeer( Keys[i].to() ); + + if( P ) { + // put name + it->setText( 1, P->name() ); + } else { + // unknown + it->setText( 1, Keys[i].to().toString() ); + } + + // and put address as sub + QListViewItem * Sub = new QListViewItem( it ); + Sub->setText( 0, D->address().toString() ); + Sub->setText( 1, Keys[i].to().toString() ); + } else { + // perhaps we are destination + D = OT->findDriver( Keys[i].to() ); + + if( D ) { + it->setText( 1, D->devname() ); + + // we are source + P = OT->findPeer( Keys[i].from() ); + + if( P ) { + // put name + it->setText( 0, P->name() ); + } else { + // unknown + it->setText( 0, Keys[i].from().toString() ); + } + + // and put address as sub + QListViewItem * Sub = new QListViewItem( it ); + Sub->setText( 0, Keys[i].from().toString() ); + Sub->setText( 1, D->address().toString() ); + } else { + // nor source nor destination -> unknown + it->setText( 0, Keys[i].from().toString() ); + it->setText( 1, Keys[i].to().toString() ); + } + } + } +} + + +OTPairing::~OTPairing() { + if( MyIcons ) + delete Icons; + OTGateway::releaseOTGateway(); +} + +void OTPairing::SLOT_Unpair( ) { + // find selected pair + + QListViewItem * it = Pairs_LV->firstChild(); + while( it ) { + if( it->isSelected() ) { + // confirm ? + if( QMessageBox::warning(0, + tr("Break pairing"), + tr("Sure ?"), + tr("Yes, break"), + tr("No, don't break") ) == 0 ) { + LinkKeyLVI * KPIt = (LinkKeyLVI *)it; + // break + OT->removeLinkKey( KPIt->index() ); + delete KPIt; + } + return; + } + it= it->nextSibling(); + } +} + +// +// +// +// +// + +OTScan::OTScan( QWidget * parent, OTIcons * _IC ) : + OTScanGUI( parent ), Filter() { + + OT = OTGateway::getOTGateway(); + Icons = (_IC ) ? _IC : new OTIcons(); + MyIcons = (_IC == 0 ); + DetectedPeers_LV->header()->hide(); + Current = 0; + SelectedPeer = 0; + SelectedChannel = 0; + + StrengthTimer = new QTimer( this ); + connect( StrengthTimer, + SIGNAL( timeout()), + this, + SLOT( SLOT_UpdateStrength()) + ); + + connect( OT, + SIGNAL( detectedPeer( OTPeer *, bool )), + this, + SLOT( SLOT_NewPeer( OTPeer *, bool )) + ); + connect( OT, + SIGNAL( finishedDetecting()), + this, + SLOT( SLOT_FinishedDetecting()) + ); + + // populate with peers we already know about + const PeerVector & P = OT->peers(); + for( unsigned int i = 0; + i < P.count(); + i ++ ) { + SLOT_NewPeer( P[i], TRUE ); + } + + // populate State fram + { QHBoxLayout * H =new QHBoxLayout( State_Frm ); + + Paired_Led = new OLedBox( green, State_Frm ); + QLabel * L1 = new QLabel( tr( "Paired" ), State_Frm ); + + H->addWidget( Paired_Led ); + H->addWidget( L1 ); + H->addStretch( 1 ); + } +} + +OTScan::~OTScan() { + if( MyIcons ) + delete Icons; + OTGateway::releaseOTGateway(); + + // send all peers that we do not care about states + QListViewItem * Lit = DetectedPeers_LV->firstChild(); + while( Lit ) { + ((PeerLVI *)Lit)->peer()->stopFindingOutState( ); + Lit = Lit->nextSibling(); + } +} + +// static scan dialog function +int OTScan::getDevice( OTPeer *& Peer, + int & Channel, + OTGateway * OT, + const UUIDVector & Filter, + QWidget* Parent ) { + bool IsUp = 0; + unsigned int i; + + // check if bluetooth is up + OTDriverList & DL = OT->getDriverList(); + for( i = 0; + i < DL.count(); + i ++ ) { + if( DL[i]->isUp() ) { + // one device that is up found + IsUp = 1; + break; + } + } + + // use this driver + OT->setScanWith( OT->driver(i) ); + + // create dialog + QDialog * Dlg = new QDialog( Parent, 0, TRUE ); + QVBoxLayout * V = new QVBoxLayout( Dlg ); + OTScan * Scn = new OTScan( Dlg ); + + connect( Scn, + SIGNAL( selected() ), + Dlg, + SLOT( accept() ) + ); + + if( Filter ) { + Scn->setScanFilter( Filter ); + } + + V->addWidget( Scn ); + Dlg->setCaption( tr("Scan Neighbourhood" ) ); + Dlg->showMaximized(); + int rv = Dlg->exec(); + + if( rv == QDialog::Accepted ) { + // get peer + Peer = Scn->selectedPeer(); + if( Peer == 0 ) { + // no peer selected + rv = QDialog::Rejected; + } else { + Channel = Scn->selectedChannel(); + } + } + + delete Dlg; + + return rv; +} + +void OTScan::setScanFilter( const UUIDVector & V ) { + Filter = V; +} + +void OTScan::resetScanFilter( void ) { + Filter.truncate(0); +} + +void OTScan::SLOT_DoScan( bool DoIt ) { + if( DoIt ) { + OT->scanNeighbourhood(); + } else { + OT->stopScanOfNeighbourhood(); + } + + scanMode( DoIt ); +} + +// double clicked on a device +void OTScan::SLOT_Selected( QListViewItem * it ) { + if( ! it ) + return; + + if( Filter.count() > 0 ) { + // filter on service + if( it->depth() == 0 ) { + // select a service and not a device + return; + } + + // store result + SelectedPeer = ((PeerLVI *)it->parent())->peer(); + SelectedChannel = ((ChannelLVI *)it)->channel(); + } else { + // click on device + if( it->depth() != 0 ) { + return; + } + + SelectedPeer = ((PeerLVI *)it)->peer(); + SelectedChannel = 0; + } + owarn << "Selected " << SelectedPeer->address().toString() << + " Channel " << SelectedChannel << oendl; + emit selected(); +} + +void OTScan::SLOT_FinishedDetecting( ) { + scanMode( false ); +} + +void OTScan::SLOT_CleanupOld( ) { + + // iterate over all peers and find those that + // are down and have no pairing info + OTPeer * TheP; + const LinkKeyArray & Keys = OT->getLinkKeys(); + + QListViewItem * Lit = DetectedPeers_LV->firstChild(); + while( Lit ) { + TheP = ((PeerLVI *)Lit)->peer(); + if( TheP->state() == OTPeer::Peer_Down ) { + unsigned int k; + + // what about linkkeys ? + for( k = 0; k < Keys.count(); k ++ ) { + if( TheP->address() == Keys[k].to() || + TheP->address() == Keys[k].from() + ) { + // part of linkkey + owarn << "LINKKEY " << TheP->address().toString() << oendl; + break; + } + } + + if( k == Keys.count() ) { + owarn << "RM LINKKEY " << TheP->address().toString() << oendl; + // not found -> remember to remove this peer + QListViewItem * Nit; + OT->removePeer( TheP ); + Nit = Lit->nextSibling(); + delete Lit; + Lit = Nit; + continue; + } + } else { + owarn << "NODOWN " << TheP->address().toString() << oendl; + } + + Lit = Lit->nextSibling(); + } +} + +void OTScan::SLOT_NewPeer( OTPeer * P, bool IsNew ){ + PeerLVI * it = 0; + + if( IsNew ) { + it = new PeerLVI( P, DetectedPeers_LV ); + } else { + // find peer in table + QListViewItem * Lit = DetectedPeers_LV->firstChild(); + while( Lit ) { + if( ((PeerLVI *)Lit)->peer() == P ) { + // this item + it = (PeerLVI *)Lit; + break; + } + Lit = Lit->nextSibling(); + } + + if( ! it ) { + owarn << "Should not occur" << oendl; + return; + } + } + + // update/show info + it->setText( 0, P->name() ); + it->setPixmap(0, Icons->deviceIcon( + OT->deviceTypeToName( P->deviceClass() ) ) ); + + // tell peer to report its state async + connect( P, + SIGNAL( peerStateReport( OTPeer *)), + this, + SLOT( SLOT_PeerState( OTPeer *)) + ); + + if( IsNew ) { + // find state + refreshState( (PeerLVI *)it, 1 ); + } else { + // update staet + SLOT_PeerState( P ); + } +} + +void OTScan::SLOT_PeerState( OTPeer * P ) { + PeerLVI * it = (PeerLVI *)DetectedPeers_LV->firstChild(); + while( it ) { + if( it->peer() == P ) { + break; + } + it = (PeerLVI * )it->nextSibling(); + } + + if( ! it ) + return; + + switch( P->state() ) { + case OTPeer::Peer_Unknown : + case OTPeer::Peer_Down : + it->setPixmap( 1, 0 ); + break; + case OTPeer::Peer_Up : + it->setPixmap( 1, Icons->loadPixmap( + ( P->connectedTo() ) ? "connected" : "notconnected" ) ); + if( it == Current && ! StrengthTimer->isActive() ) { + // start showing strength + StrengthTimer->start( 1000, FALSE ); + SLOT_UpdateStrength(); + } + break; + } +} + +void OTScan::SLOT_RefreshState( void ) { + + QListViewItem * it = DetectedPeers_LV->firstChild(); + while( it ) { + if( it->isSelected() ) { + break; + } + it = it->nextSibling(); + } + + if( ! it ) + return; + + refreshState( (PeerLVI *)it, 1 ); +} + +void OTScan::refreshState( PeerLVI * it, bool Force ) { + it->setPixmap( 1, Icons->loadPixmap( "find" ) ); + it->peer()->findOutState( 30, Force ); +} + +void OTScan::SLOT_Show( QListViewItem * it ) { + + if( ! it || it->depth() > 0 ) + return; + + QString S; + + Current = (PeerLVI *)it; + + Strength_PB->setProgress( 0 ); // reset + Address_LBL->setText( Current->peer()->address().toString() ); + Peer_GB->setTitle( Current->peer()->name() ); + + const LinkKeyArray & Keys = OT->getLinkKeys(); + + Paired_Led->setOn( FALSE ); + for( unsigned int i = 0; + i < Keys.count(); + i ++ ) { + if( Current->peer()->address() == Keys[i].to() ) { + Paired_Led->setOn( TRUE ); + break; + } + } + + if( Current->peer()->state() == OTPeer::Peer_Up ) { + RefreshServices_But->setEnabled( TRUE ); + StrengthTimer->start( 1000, FALSE ); + SLOT_UpdateStrength(); + } else { + RefreshServices_But->setEnabled( FALSE ); + } + +} + +void OTScan::SLOT_UpdateStrength( void ) { + OTDriver * D = Current->peer()->connectedTo(); + + if( D ) { + long Q = D->getLinkQuality( Current->peer()->address() ); + Strength_PB->setProgress( Q ); + if( ! Q ) { + // no quality + Strength_PB->setEnabled( TRUE ); + StrengthTimer->stop(); + } + } else { + Strength_PB->setEnabled( FALSE ); + Strength_PB->setProgress( 0 ); + // no point in continuing + StrengthTimer->stop(); + } +} + +void OTScan::SLOT_RefreshServices( void ) { + + QListViewItem * it = DetectedPeers_LV->firstChild(); + while( it ) { + if( it->isSelected() ) { + break; + } + it = it->nextSibling(); + } + + if( ! it ) + return; + + QString S; + PeerLVI * PI = (PeerLVI *)it; + + scanMode( true ); + qApp->processEvents(0); + + ServiceVector & V = PI->peer()->services(); + + while( PI->firstChild() ) { + // remove children + delete PI->firstChild(); + } + + for( unsigned int i = 0 ; + i < V.count(); + i ++ ) { + QString S; + S = V[i]->name(); + + if( S.isEmpty() ) { + continue; + } + + { QListViewItem * SIt; + UUIDVector UIDV; + QPixmap Pm; + bool Done = 0; + bool R; + short ID; + + SIt = 0; + + UIDV = V[i]->classIDList(); + // first all UUID ! 1200 12ff (Genericprofiles) + for( unsigned int j = 0; + j < UIDV.count(); + j ++ ) { + + if( Filter.count() ) { + bool FilterOut = 1; + // filter out if not in list + for( unsigned int ff = 0; + ff < Filter.count(); + ff ++ ) { + if( UIDV[j] == Filter[ff] ) { + FilterOut = 0; + break; + } + } + + if( FilterOut ) { + // not in filter list + continue; + } + } // else show + + ID = UIDV[j].toShort(); + if( ID < 0x1200 || ID > 0x12ff ) { + // use this profile + if( R ) { + unsigned int ch; + bool has; + has = V[i]->rfcommChannel( ch ); + SIt = new ChannelLVI( (has) ? (int)ch : -1 , PI ); + SIt->setText(0, V[i]->name() ); + + Pm = Icons->serviceIcon( ID, R ); + SIt->setPixmap(0, Pm ); + Done = 1; + break; + } + } + } + + if( ! Done ) { + // check other range too + for( unsigned int j = 0; + j < UIDV.count(); + j ++ ) { + + if( Filter.count() ) { + bool FilterOut = 1; + // filter out if not in list + for( unsigned int ff = 0; + ff < Filter.count(); + ff ++ ) { + if( UIDV[j] == Filter[ff] ) { + FilterOut = 0; + break; + } + } + + if( FilterOut ) { + // not in filter list + continue; + } + } // else show + + ID = UIDV[j].toShort(); + if( ID >= 0x1200 && ID <= 0x12ff ) { + // use this profile + unsigned int ch; + bool has; + has = V[i]->rfcommChannel( ch ); + SIt = new ChannelLVI( (has) ? (int)ch : -1 , PI ); + SIt->setText(0, V[i]->name() ); + + Pm = Icons->serviceIcon( ID, R ); + SIt->setPixmap(0, Pm ); + + break; + } + } + } + + } + } + + scanMode( false ); +} + +void OTScan::scanMode( bool M ) { + // avoid infinite loop because it triggers DoScan + Detect_But->blockSignals( TRUE ); + Detect_But->setOn( M ); + Detect_But->setText( (M) ? tr("Scanning") : tr("Scan") ); + Detect_But->blockSignals( FALSE ); +} + +// +// +// +// +// + +OTManage::OTManage( QWidget * parent, OTIcons * _IC ) : + OTManageGUI( parent ) { + + OT = OTGateway::getOTGateway(); + + Icons = (_IC ) ? _IC : new OTIcons(); + MyIcons = (_IC == 0 ); + AllDrivers_LV->setSorting(-1); + + connect( OT, + SIGNAL( driverListChanged() ), + this, + SLOT( SLOT_DriverListChanged() ) + ); + connect( OT, + SIGNAL( stateChange( OTDriver *, bool ) ), + this, + SLOT( SLOT_StateChange( OTDriver *, bool ) ) + ); + + SLOT_DriverListChanged(); + + AllDrivers_LV->header()->hide(); +} + +OTManage::~OTManage() { + if( MyIcons ) + delete Icons; + OTGateway::releaseOTGateway(); +} + +void OTManage::SLOT_ShowDriver( QListViewItem * It ) { + if( It == 0 || It->depth() > 0 ) + // not toplevel + return; + + DriverLVI * it = (DriverLVI *) It; + DriverIsUp_CB->setChecked( it->driver()->isUp() ); +} + +void OTManage::SLOT_UpDriver( bool Up ) { + QListViewItem * it = AllDrivers_LV->firstChild(); + while( it ) { + if( it->isSelected() ) { + OTDriver * D = ((DriverLVI *)it)->driver(); + owarn << "UP driver " << D->devname() << oendl; + // this + D->setUp( Up ); + return; + } + it = it->nextSibling(); + } +} + +void OTManage::SLOT_StateChange( OTDriver * D, bool Up ) { + QListViewItem * it = AllDrivers_LV->firstChild(); + while( it ) { + if( ((DriverLVI *)it)->driver() == D ) { + it->setPixmap( 0, + Icons->loadPixmap( ( Up ) ? "bluezon" : "bluezoff" ) ); + return; + } + it = it->nextSibling(); + } +} + +void OTManage::SLOT_DriverListChanged( ) { + DriverLVI * It; + QListViewItem * Sub; + QListViewItem * First = 0; + OTDriver* D; + OTDriverList & DL = OT->getDriverList(); + + AllDrivers_LV->clear(); + for( unsigned int i = 0; + i < DL.count(); + i ++ ) { + D = DL[i]; + It = new DriverLVI( D, AllDrivers_LV ); + + if( ! First ) + First = It; + + It->setText( 0, D->devname() ); + It->setPixmap( 0, + Icons->loadPixmap( (D->isUp()) ? + "bluezon" : "bluezoff" ) ); + + Sub = new QListViewItem( It ); + Sub->setText( 0, tr( "Name" ) ); + Sub->setText( 1, D->name() ); + + Sub = new QListViewItem( It ); + Sub->setText( 0, tr( "Address" ) ); + Sub->setText( 1, D->address().toString() ); + + Sub = new QListViewItem( It ); + Sub->setText( 0, tr( "Revision" ) ); + Sub->setText( 1, D->revision() ); + + Sub = new QListViewItem( It ); + Sub->setText( 0, tr( "Manufacturer" ) ); + Sub->setText( 1, D->manufacturer() ); + + QString Service, Device; + D->getClass( Service, Device ); + + Sub = new QListViewItem( It ); + Sub->setText( 0, tr( "Service classes" ) ); + Sub->setText( 1, Service ); + Sub = new QListViewItem( It ); + Sub->setText( 0, tr( "Device class" ) ); + Sub->setText( 1, Device ); + } + + if( DL.count() ) { + AllDrivers_LV->setCurrentItem( First ); + DriverIsUp_CB->setEnabled( TRUE ); + } else { + DriverIsUp_CB->setChecked( FALSE ); + DriverIsUp_CB->setEnabled( FALSE ); + } +} + +void OTManage::SLOT_SetRefreshTimer( int v ) { + OT->setRefreshTimer( v * 1000 ); +} + +// +// +// +// +// + +OTMain::OTMain( QWidget * parent ) : OTMainGUI( parent ) { + + Icons = new OTIcons(); + OT = OTGateway::getOTGateway(); + + connect( OT, + SIGNAL( deviceEnabled( bool ) ), + this, + SLOT( SLOT_DeviceIsEnabled( bool ) ) + ); + connect( OT, + SIGNAL( driverListChanged() ), + this, + SLOT( SLOT_DriverListChanged() ) + ); + connect( OT, + SIGNAL( stateChange( OTDriver *, bool ) ), + this, + SLOT( SLOT_StateChange( OTDriver *, bool ) ) + ); + + if( ! OT->needsEnabling() ) { + MustBeEnabled_CB->hide(); + } else { + // detect current state + MustBeEnabled_CB->setChecked( + OT->isEnabled() ); + } + + SLOT_DriverListChanged(); +} + +OTMain::~OTMain() { + OTGateway::releaseOTGateway(); + delete Icons; +} + +void OTMain::SLOT_DriverListChanged() { + OTDriver * D; + OTDriverList & DL = OT->getDriverList(); + + DeviceList_CB->clear(); + for( unsigned int i = 0; + i < DL.count(); + i ++ ) { + D = DL[i]; + DeviceList_CB->insertItem( + Icons->loadPixmap( (D->isUp()) ? + "bluezon" : "bluezoff" ), + D->devname() ); + if( D == OT->scanWith() ) { + DeviceList_CB->setCurrentItem( i ); + } + } + + Scan_But->setEnabled( OT->getDriverList().count() > 0 ); + DeviceList_CB->setEnabled( OT->getDriverList().count() > 0 ); +} + +void OTMain::SLOT_EnableBluetooth( bool Up ) { + OT->SLOT_SetEnabled( Up ); +} + +void OTMain::SLOT_DeviceIsEnabled( bool Up ) { + MustBeEnabled_CB->blockSignals( TRUE ); + MustBeEnabled_CB->setChecked( Up ); + MustBeEnabled_CB->blockSignals( FALSE ); +} + +void OTMain::SLOT_Manage( void ) { + QDialog * Dlg = new QDialog( this, 0, TRUE ); + QVBoxLayout * V = new QVBoxLayout( Dlg ); + OTManage * Mng = new OTManage( Dlg, Icons ); + + V->addWidget( Mng ); + + Dlg->setCaption( tr("Manage local devices" ) ); + Dlg->showMaximized(); + Dlg->exec(); + delete Dlg; +} + +void OTMain::SLOT_Scan( void ) { + OTDriverList & DL = OT->getDriverList(); + for( unsigned int i = 0; + i < DL.count(); + i ++ ) { + if( DL[i]->isUp() && + DL[i]->devname() == DeviceList_CB->currentText() + ) { + QDialog * Dlg = new QDialog( this, 0, TRUE ); + QVBoxLayout * V = new QVBoxLayout( Dlg ); + OTScan * Scn = new OTScan( Dlg, Icons ); + + OT->setScanWith( OT->driver(i) ); + V->addWidget( Scn ); + Dlg->setCaption( tr("Scan Neighbourhood" ) ); + Dlg->showMaximized(); + Dlg->exec(); + + delete Dlg; + return; + } + } + +} + +void OTMain::SLOT_StateChange( OTDriver * D, bool Up ) { + for( int i = 0; + i < DeviceList_CB->count(); + i ++ ) { + if( DeviceList_CB->text(i) == D->devname() ) { + DeviceList_CB->changeItem( + Icons->loadPixmap( (Up) ? "bluezon" : "bluezoff" ), + D->devname(), + i ); + return; + } + } +} + +void OTMain::SLOT_Pairing( void ) { + QDialog * Dlg = new QDialog( this, 0, TRUE ); + QVBoxLayout * V = new QVBoxLayout( Dlg ); + OTPairing * Pair = new OTPairing( Dlg, Icons ); + + V->addWidget( Pair ); + Dlg->showMaximized(); + Dlg->setCaption( tr("Manage pairing" ) ); + Dlg->exec(); + + delete Dlg; +} diff --git a/noncore/settings/networksettings2/opietooth2/Opietooth.h b/noncore/settings/networksettings2/opietooth2/Opietooth.h new file mode 100644 index 0000000..9e53fcb --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/Opietooth.h @@ -0,0 +1,194 @@ +#ifndef OPIETOOTH_H +#define OPIETOOTH_H + +#include <OTIcons.h> + +#include <OTPairingGUI.h> +class OLedBox; + +namespace Opietooth2 { + +class OTGateway; +class OTDriver; +class OTInquiry; +class OTPeer; +class PeerLVI; + +class OTPairing : public OTPairingGUI { + + Q_OBJECT + +public : + + OTPairing( QWidget * parent, + OTIcons * _Ic = 0 ); + ~OTPairing(); + +private slots : + + void SLOT_Unpair( void ); + +signals : + +protected : + +private : + + bool MyIcons; + OTIcons * Icons; + OTGateway * OT; +}; +}; + +#include <OTScanGUI.h> + +namespace Opietooth2 { + +class OTGateway; +class OTDriver; +class OTInquiry; +class OTPeer; + +class OTScan : public OTScanGUI { + + Q_OBJECT + +public : + + OTScan( QWidget * parent, + OTIcons * _Ic = 0 ); + ~OTScan(); + + // static function to return a device and a channel + static int getDevice( OTPeer *& Peer, + int & Channel, + OTGateway * OT, + const UUIDVector & Filter = 0, + QWidget* Parent = 0); + + // show only services that match any of the filter + void setScanFilter( const UUIDVector & Filter ); + void resetScanFilter( void ); + + inline OTPeer * selectedPeer( void ) + { return SelectedPeer; } + inline int selectedChannel( void ) + { return SelectedChannel; } + +public slots : + +private slots : + + void SLOT_DoScan( bool ); + void SLOT_NewPeer( OTPeer *, bool ); + void SLOT_FinishedDetecting(); + void SLOT_Show( QListViewItem *); + void SLOT_RefreshServices( void ); + void SLOT_RefreshState( void ); + void SLOT_CleanupOld( void ); + void SLOT_UpdateStrength( void ); + void SLOT_PeerState( OTPeer * ); + void SLOT_Selected( QListViewItem * ); + +signals : + + void selected( void ); + +protected : + +private : + + void refreshState( PeerLVI *, bool ); + void scanMode( bool ); + + // load scanned devices + + bool MyIcons; + OTIcons * Icons; + OTGateway * OT; + OTInquiry * Scanning; + UUIDVector Filter; + + OLedBox * Paired_Led; + QTimer * StrengthTimer; + PeerLVI * Current; + + OTPeer * SelectedPeer; + int SelectedChannel; +}; +}; + +#include <OTManageGUI.h> +namespace Opietooth2 { + +class OTManage : public OTManageGUI { + + Q_OBJECT + +public : + + OTManage( QWidget * parent, + OTIcons * _IC = 0 ); + ~OTManage(); + +public slots : + +private slots : + + void SLOT_ShowDriver( QListViewItem * ); + void SLOT_UpDriver( bool ); + void SLOT_StateChange( OTDriver * , bool ); + void SLOT_DriverListChanged(); + void SLOT_SetRefreshTimer( int ); + +signals : + +protected : + +private : + + // load scanned devices + + bool MyIcons; + OTIcons * Icons; + OTGateway * OT; + OTInquiry * Scanning; +}; +}; + +#include <OTMainGUI.h> + +namespace Opietooth2 { +class OTMain : public OTMainGUI { + + Q_OBJECT + +public : + + OTMain( QWidget * parent ); + ~OTMain(); + +public slots : + +private slots : + + void SLOT_Pairing( void ); + void SLOT_Manage( void ); + void SLOT_Scan( void ); + void SLOT_EnableBluetooth( bool ); + void SLOT_DriverListChanged(); + void SLOT_DeviceIsEnabled( bool ); + void SLOT_StateChange( OTDriver * , bool ); + +signals : + +protected : + +private : + + // load scanned devices + OTIcons * Icons; + OTGateway * OT; +}; +}; +#endif diff --git a/noncore/settings/networksettings2/opietooth2/bluezlib.h b/noncore/settings/networksettings2/opietooth2/bluezlib.h new file mode 100644 index 0000000..c431574 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/bluezlib.h @@ -0,0 +1,28 @@ +#ifndef BLUEZLIB_H +#define BLUEZLIB_H + +#include <signal.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> + +extern "C" { +#include <bluetooth/bluetooth.h> +#include <bluetooth/hci.h> +#include <bluetooth/hci_lib.h> +#include <bluetooth/sdp.h> +#include <bluetooth/sdp_lib.h> +#include <bluetooth/l2cap.h> +#include <bluetooth/bnep.h> +#include <bluetooth/rfcomm.h> +} + +#define BT_DISABLED 0 +#define BT_ENABLED 1 +#define BT_UNKNOWN 2 +#define BTVALUE(x) ((x)?BT_ENABLED:BT_DISABLED) + +#endif diff --git a/noncore/settings/networksettings2/opietooth2/config.in b/noncore/settings/networksettings2/opietooth2/config.in new file mode 100644 index 0000000..720f49a --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/config.in @@ -0,0 +1,5 @@ +config NS2OPIETOOTH + boolean "opie-networksettings2 bluetooth library" + default "y" + depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE2CORE + diff --git a/noncore/settings/networksettings2/opietooth2/libopietooth2.control b/noncore/settings/networksettings2/opietooth2/libopietooth2.control new file mode 100644 index 0000000..fd01fb5 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/libopietooth2.control @@ -0,0 +1,9 @@ +Package: libopietooth2 +Files: lib/libopietooth2.so.* apps/Settings/opietooth-manager.desktop pics/opietooth/*.png pics/opietooth/icons/*.png +Priority: optional +Section: opie/system +Maintainer: wim delvaux <wim.delvaux@handhelds.org> +Architecture: arm +Version: $QPE_VERSION$EXTRAVERSION +Depends: task-opie-minimal, libbluetooth1, opie-bluepin | opie-multiauth-bluepingplugin, bluez-utils-nodbus +Description: Opie bluetooth support library version 2 diff --git a/noncore/settings/networksettings2/opietooth2/libopietooth2.postinst b/noncore/settings/networksettings2/opietooth2/libopietooth2.postinst new file mode 100755 index 0000000..cd605c2 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/libopietooth2.postinst @@ -0,0 +1,10 @@ +#!/bin/sh + +QTPB=/opt/QtPalmtop/bin + +[ ! -L ${QTPB}/networksettings2-opietooth ] && ln -sf ${QTPB}/networksettings2 ${QTPB}/networksettings2-opietooth + +# qcop QPE/Taskbar "linkChanged(opietooth)" +qcop QPE/Taskbar "reloadApps()" + +exit 0 diff --git a/noncore/settings/networksettings2/opietooth2/opietooth2.pro b/noncore/settings/networksettings2/opietooth2/opietooth2.pro new file mode 100644 index 0000000..590b656 --- a/dev/null +++ b/noncore/settings/networksettings2/opietooth2/opietooth2.pro @@ -0,0 +1,37 @@ +TEMPLATE = lib +CONFIG += qt warn_on release +#CONFIG += qt warn_on debug +DESTDIR = $(OPIEDIR)/lib$(PROJMAK) +HEADERS = OTDevice.h \ + OTDriver.h \ + OTGateway.h \ + OTHCISocket.h \ + OTInquiry.h \ + OTDeviceAddress.h \ + OTIcons.h \ + OTUUID.h \ + OTSDPAttribute.h \ + OTSDPService.h \ + OTPeer.h \ + Opietooth.h +SOURCES = OTDevice.cpp \ + OTDriver.cpp \ + OTDriverList.cpp \ + OTHCISocket.cpp \ + OTInquiry.cpp \ + OTDeviceAddress.cpp \ + OTUUID.cpp \ + OTSDPAttribute.cpp \ + OTSDPService.cpp \ + OTIcons.cpp \ + OTPeer.cpp \ + OTGateway.cpp \ + Opietooth.cpp +INCLUDEPATH += $(OPIEDIR)/include +DEPENDPATH += $(OPIEDIR)/include +LIBS += -lqpe -lopiecore2 -lbluetooth +INTERFACES = OTMainGUI.ui OTScanGUI.ui OTManageGUI.ui OTPairingGUI.ui +TARGET = opietooth2 +VERSION = 1.0.0 + +include ( $(OPIEDIR)/include.pro ) |