×

Discussion Board

Results 1 to 2 of 2
  1. #1
    Registered User
    Join Date
    Jun 2008
    Posts
    17

    Thumbs up Some useful issues about bluetooth (at least for C++)

    Hi All,

    I hope - that text helps somebody during research of BT problems.
    In our application it was required to establish SPP connection over BT (with GPS receiver or Car-Kit which also sends GPS data). Parallel the phone uses the A2DP or the HFP to pass the Audio to the Car-Kit.

    Here is description of some problems and solutions (works at S60, tested with N95).

    1) If you call the Notifier to get the BT Power "On", and the BT Power was already "On" - the existing audio BT connection will be broken (so if you already have the audio connection before that notifier call - it will be stopped from Symbian).
    Solution: check if the BT is off before call that notifier:

    Code:
    TInt MyClass::GetCurrentPowerState()
    {
        CRepository *crep = CRepository::NewL(KCRUidBluetoothPowerState);
        TInt value=0;
        CleanupStack::PushL( crep );
        User::LeaveIfError( crep->Get(KBTPowerState, value) );
        CleanupStack::PopAndDestroy( crep );
        return value;
    }
    
    if (EBTPowerOn == GetCurrentPowerState())
    {
        // the BT is already "on", just do what you like to do
    }
    else
    {
        User::LeaveIfError(MyRNotifier.Connect());
        MyRNotifier.StartNotifierAndGetResponse(
                        iStatus,
                        KPowerModeSettingNotifierUid,
                        m_pckg,
                        m_result);
        SetActive();
    }
    2) If you call "connect" for the RSocket to the BT device (given by Address and Port), which is not more present (i.e. turned off) - the existing audio connection will be broken.
    Solution: try to discover the services at the target BT-device before connect to it (You don't need to discover the devices, just discover the services for known address).
    Note: discovering the services at BT devices (so far as discovering of BT devices) "loads" the BT - so the audio transmition (sound) will be interrupted, but will stay "alive" (so the audio connection will not be broken). To avoid a high loading of audio connection through services discovering - add an adaptive timeout between trying to reconnect. For example - initially try to reconnect 3 times with delay = 5 seconds between reconnections, then try to connect each 40 seconds. So far the connection was established - you can reset the counter of timeouts.
    I'm talking here about connection to the already known device (i.e. to address which is already saved in your program configuration as "last used"). In case you just connect to the device which was discovered right now (i.e. which was selected by user from corresponding dialog) - you don't need such complex behaviour, just connect to it.

    If the device is here - the discovering of first SPP service goes really fast (less that 2 seconds), so you can use it before each connection. In case the device is not present - it takes longer, so you need a timeout to abort the discovering (for example - 5 seconds).

    Hope, that helps for somebody.

    Good Luck!
    Andrey

  2. #2
    Registered User
    Join Date
    Jun 2008
    Posts
    17

    Thumbs up Re: Some useful issues about bluetooth (at least for C++)

    P.S. here is the example of checker - if the device is still here (i.e. Discover of SPP services):

    // Header

    Code:
    #ifndef CBTDeviceDiscover_h
    #define CBTDeviceDiscover_h 1
    
    // required capabilities: LocalServices
    // used libraries: sdpagent.lib, sdpdatabase.lib
    
    #include <btsdp.h>
    
    
    // determines template for callback class/function which is used by CBTDeviceDiscover so far it gets result
    class CBTDeviceDiscover_CallBack
    {
        public:
            // callback function declaration to be implemented in your class; bDevicePresent=true if the device was found;
            virtual void BTDeviceDiscovered( bool bDevicePresent, TUint uiPort, bool bPortValid ) = 0;
    };
    
    
    // class CBTDeviceDiscover used to check if the BT device with given address is still present (by discovering the services of device)
    class CBTDeviceDiscover : public CBase,
                              public MSdpAgentNotifier,
                              public MSdpAttributeValueVisitor
    {
        public:
            
            // constructor
            CBTDeviceDiscover(CBTDeviceDiscover_CallBack & rCallBackClass);
            
            // destructor
            ~CBTDeviceDiscover();
            
            // discover if the device with given address present (asynchronous).
            void DiscoverDeviceL(TBTDevAddr & devAddr);
            
            // stopes the discovery (aborts it and delete variables used for it) 
            void StopDiscovery();
    
        private:
            
            // from MSdpAgentNotifier:
            void NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount);
            void AttributeRequestResult(TSdpServRecordHandle aHandle, TSdpAttributeID aAttrID, CSdpAttrValue* aAttrValue);
            void AttributeRequestComplete(TSdpServRecordHandle aHandle, TInt aError);
                    
            // from MSdpAttributeValueVisitor:
            void VisitAttributeValueL(CSdpAttrValue &aValue, TSdpElementType aType); // Called for processing of each service attribute.
            void StartListL(CSdpAttrValueList &aList); // should be declared, but not needed to be implemented
            void EndListL(); // should be declared, but not needed to be implemented
                    
            // member variables:
            
            CBTDeviceDiscover_CallBack & m_rCallBackClass; // reference to callback class used if the discovery is finished
            TBTDevAddr m_devAddr; // BT device address
            CSdpAgent * m_pAgent; // Service discovery agent
            CSdpSearchPattern * m_pSearchPattern; // Service discovery search pattern
            TUUID m_uiCurrUUID; // currently discovered attribute uuid in the service attributes
            TUint m_uiPort; // Port (comm channel) found in the service attributes
            bool m_bPortValid; // true if the Port was retrieved
            bool m_bDiscovering; // true if currently discovering the device (if interested on results of listener functions) 
    };
    
    #endif // #ifndef CBTDeviceDiscover_h
    // Source file:

    Code:
    #include <bt_sock.h>
    // don't forget to adapt to your paths
    #include "CBTDeviceDiscover.h"
    
    
    CBTDeviceDiscover::CBTDeviceDiscover(CBTDeviceDiscover_CallBack & rCallBackClass)
        : m_rCallBackClass(rCallBackClass),
          m_pAgent(NULL),
          m_pSearchPattern(NULL),
          m_uiCurrUUID(0),
          m_uiPort(0),
          m_bPortValid(FALSE),
          m_bDiscovering(FALSE)
    {
        m_devAddr.Reset();
    }
    
    CBTDeviceDiscover::~CBTDeviceDiscover()
    {
        StopDiscovery();
    }
    
    void CBTDeviceDiscover::DiscoverDeviceL(TBTDevAddr & devAddr)
    {   
        StopDiscovery(); // to avoid conflicts if called several times before the old discovery is finished
        
        const TInt BT_UUID_SPP_SP = 0x1101; // SPP (Serial Port) UUID
        m_devAddr = devAddr;
        
        // Init new service discovery agent
        m_pAgent = CSdpAgent::NewL( *this, m_devAddr );
        
        // Set search properties for agent (use SPP service-UUID to filter the services discovered)
        m_pSearchPattern = CSdpSearchPattern::NewL();
        m_pSearchPattern->AddL(BT_UUID_SPP_SP);
        m_pAgent->SetRecordFilterL(*m_pSearchPattern);
        
        m_bDiscovering = TRUE;
        // Initiate search, result will be received with call of NextRecordRequestComplete()
        m_pAgent->NextRecordRequestL();
    }
    
    void CBTDeviceDiscover::StopDiscovery()
    {
        m_bDiscovering = FALSE;
        if(m_pAgent)
        {
            m_pAgent->Cancel();
            delete m_pAgent;
            m_pAgent = NULL;
        }
        if(m_pSearchPattern)
        {
            m_pSearchPattern->Reset();
            delete m_pSearchPattern;
            m_pSearchPattern = NULL;
        }
        m_bPortValid = FALSE;
        m_uiPort = 0; // the BT port is unknown
    }
    
    // called when the service discovery agent has completed discovering services on device (i.e. if next service found or not)
    void CBTDeviceDiscover::NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount)
    {
        if ( ( KErrNone==aError) && (0<aTotalRecordsCount) )
        {
            // We got next service record, request protocol descriptor to retrieve remote port
            // (it calls later the AttributeRequestResult() when the answer is ready)
            TRAPD(err,m_pAgent->AttributeRequestL(aHandle, KSdpAttrIdProtocolDescriptorList));
            if( err )
            {
                StopDiscovery();
                m_rCallBackClass.BTDeviceDiscovered(true, 0, false);
            }
        }
        else
        {
            // no any services found or error occures (probably the device is not present or SPP service is not present)
            StopDiscovery();
            m_rCallBackClass.BTDeviceDiscovered(false, 0, false);
        }
    }
    
    // Called when the service attributes for the service record have been retrieved.
    void CBTDeviceDiscover::AttributeRequestResult(TSdpServRecordHandle, TSdpAttributeID,
            CSdpAttrValue* aAttrValue)
    {
        // can't ignore the call of this function because we need take care about aAttrValue
    
        // Parse attributes, it will return results by several calls of VisitAttributeValue()
        TRAPD( err, aAttrValue->AcceptVisitorL(*this) );
        if( err )
        {
            StopDiscovery();
            m_rCallBackClass.BTDeviceDiscovered(true, 0, false);
        }
        delete aAttrValue;
    }
    
    // Called when the request to resolve the service attributes for the service record completes.
    void CBTDeviceDiscover::AttributeRequestComplete(TSdpServRecordHandle, TInt aError)
    {
        m_rCallBackClass.BTDeviceDiscovered(true, m_uiPort, m_bPortValid);
        // if KErrNone ==aError and we need not just the first SPP service but check several services,
        // can call for m_pAgent->NextRecordRequestL() here (and add corresponded processing in
        // NextRecordRequestComplete() )
        if (KErrNone != aError)
        {
            // Error processing (if required)
        }
        StopDiscovery();
    }
        
    // Called for processing of each service attribute.
    void CBTDeviceDiscover::VisitAttributeValueL(CSdpAttrValue &aValue, TSdpElementType aType)
    {
        if ( ! m_bDiscovering )
        {
            return; // ignore calls to that function if not discovering currently
        }
        
        // Check for attributes of UUID type. If the UUID is RFCOMM UUID, resolve the value for this attribute,
        // which will be the channel number.
        switch (aType)
        {
            case ETypeUUID: // UUID of attribute, store it 
            {
                TPtrC8 uuid(aValue.UUID().ShortestForm());
                m_uiCurrUUID.SetL(uuid);
                break;
            }
            case ETypeUint: // uint value, check if the current attribute type is KRFCOMM, store the port value if "yes"
            {
                if ( m_uiCurrUUID==KRFCOMM )
                {
                    m_uiPort=aValue.Uint();
                    m_bPortValid = TRUE;
                    m_bDiscovering = FALSE;
                }
                break;
            }
            default:
                // other attributes are not interesting for processing...
                break;
        }
    }
    
    void CBTDeviceDiscover::StartListL(CSdpAttrValueList&)
    {
    }
    
    void CBTDeviceDiscover::EndListL()
    {
    }

Similar Threads

  1. Bluesoleil Software
    By kencooper in forum Bluetooth Technology
    Replies: 9
    Last Post: 2008-08-29, 19:46
  2. Bluelet - Rapid Bluetooth App Development (Free source)
    By huiben in forum Mobile Java General
    Replies: 4
    Last Post: 2008-07-25, 15:52
  3. Bluetooth State
    By satyadeepg in forum Mobile Java Networking & Messaging & Security
    Replies: 2
    Last Post: 2007-06-10, 18:11
  4. Bluetooth GPS simulator for j2me phone
    By vgps in forum Mobile Java Networking & Messaging & Security
    Replies: 2
    Last Post: 2007-02-09, 04:30
  5. Bluetooth Emulation
    By aohx075 in forum Mobile Java Tools & SDKs
    Replies: 0
    Last Post: 2004-08-24, 04:14

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×