#include "S60QBluetooth.h" #include "S60QBluetoothPrivate.h" // INCLUDE FILES #include // for input dialogs #include #include "Common.h" #include "DeviceDiscoverer.h" #include "ServiceAdvertiser.h" #include "ServiceDiscoverer.h" #include "Listener.h" #include "Connector.h" //#include S60QBluetoothPrivate* S60QBluetoothPrivate::NewL( S60QBluetooth* aAppUi) { S60QBluetoothPrivate* self = S60QBluetoothPrivate::NewLC(aAppUi); CleanupStack::Pop(self); return self; } S60QBluetoothPrivate* S60QBluetoothPrivate::NewLC( S60QBluetooth* aAppUi) { S60QBluetoothPrivate* self = new (ELeave) S60QBluetoothPrivate(aAppUi); CleanupStack::PushL(self); self->ConstructL(); return self; } // Standard EPOC 2nd phase constructor void S60QBluetoothPrivate::ConstructL() { // get socket server session User::LeaveIfError(iSocketServ.Connect()); // init listener iListener = CListener::NewL(*this, iSocketServ); // init device discoverer iDeviceDiscoverer = CDeviceDiscoverer::NewL(iSocketServ, *this); // init service advertiser iServiceAdvertiser = CServiceAdvertiser::NewL(); // init service discoverer iServiceDiscoverer = CServiceDiscoverer::NewL(*this); // clean connections table to begin with for ( TInt idx=0; idx < KMaxConnectedDevices; idx++ ) { iConnectedDevices[idx] = NULL; } } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::S60QBluetoothPrivate( // CBluetoothPMPExampleAppUi* aAppUi) // // constructor // ---------------------------------------------------------------------------- S60QBluetoothPrivate::S60QBluetoothPrivate(S60QBluetooth* aAppUi): iIsSlave(EFalse), iAppUi(aAppUi) { //Nothing to do } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::~S60QBluetoothPrivate() // // destructor // ---------------------------------------------------------------------------- S60QBluetoothPrivate::~S60QBluetoothPrivate() { // disconnect all devices and clean up connections table DisconnectDevices(); // stop and kill helpers delete iServiceAdvertiser; iServiceAdvertiser=NULL; delete iListener; iListener=NULL; delete iDeviceDiscoverer; iDeviceDiscoverer = NULL; delete iServiceDiscoverer; iServiceDiscoverer=NULL; iSocketServ.Close(); // wipe device data list iDevDataList.ResetAndDestroy(); } // ---------------------------------------------------------------------------- // ShowMessageL( // const TDesC& aMsg, TBool aDrawLine=EFalse) // // displays text referenced by aMsg in the label, will append the aMsg in the // existing text // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::ShowMessageL(const TDesC& aMsg, TBool aDrawLine=EFalse) { /*if( aDrawLine ) iAppUi.Container().DrawLineL(); iAppUi.Container().ShowMessageL(aMsg);*/ QString message = QString::fromUtf16(aMsg.Ptr(), aMsg.Length()); emit this->iAppUi->message(message); } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::DiscoverDevicesL() // // discover bluetooth devices within range. // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::DiscoverDevicesL() { //timing: iStartTime.HomeTime(); ShowMessageL(KDiscDevicesTxt, ETrue); iDeviceDiscoverer->DiscoverDevicesL(&iDevDataList); } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::DiscoverServicesL() // // discover services provided by the discovered devices. // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::DiscoverServicesL() { iStartTime.HomeTime(); ShowMessageL(KDiscServicesTxt, ETrue); iServiceDiscoverer->DiscoverServicesL(&iDevDataList); } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::StartSlaveL() // // set application in slave mode. the device will be set to listen to // a bluetooth channel, and advertise its service on the channel. // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::StartSlaveL() { if ( iIsSlave ) return; ShowMessageL(KSlaveInitTxt, ETrue); TInt channel; iListener->StartListenerL(channel); TBuf msg; msg.AppendFormat(KListeningTxt, channel); ShowMessageL(msg, EFalse); iServiceAdvertiser->StartAdvertiserL(channel); ShowMessageL(KSlaveInitCompTxt, EFalse); iIsSlave=ETrue; } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::DisconnectDevices() // // disconnect connected devices and clean up connections table // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::DisconnectDevices() { for ( TInt idx=0; idx= KMaxConnectedDevices ) return; TDeviceData *dev = iDevDataList[idx]; connector = CConnector::NewL(*this, iSocketServ); CleanupStack::PushL(connector); // if matching service on remote device was found, the service port // is set and will be > 0. if so, we can attempt to connect. if ( dev->iDeviceServicePort>0 ) { QString __device = QString::fromUtf16(dev->iDeviceName.Ptr(), dev->iDeviceName.Length()); emit iAppUi->message("connecting to "+__device); if ( (connector->ConnectL(dev->iDeviceName, dev->iDeviceAddr, dev->iDeviceServicePort))==KErrNone ) { iConnectedDevices[iConnectedDeviceCount] = connector; iConnectedDeviceCount++; //metrics = CBluetoothPhysicalLinkMetrics::NewL(*this, iSocketServ, dev->iDeviceAddr); //metrics->SubscribeRssi(); // metrics->SubscribeTransmitPowerLevel(); //metrics->SubscribeLinkQuality(); } else { // connection to device failed!! delete connector; QString _device = QString::fromUtf16(dev->iDeviceName.Ptr(), dev->iDeviceName.Length()); emit iAppUi->error("connection to device "+_device+" failed!!"); } } else { QString ___device = QString::fromUtf16(dev->iDeviceName.Ptr(), dev->iDeviceName.Length()); emit iAppUi->error("service port of device "+___device+" "+QString::number(dev->iDeviceServicePort)); } CleanupStack::Pop(connector); } ShowConnectedDevicesL(); } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::ShowConnectedDevicesL() // // display the devices we are connected to // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::ShowConnectedDevicesL() { TInt count=0; ShowMessageL(KConnDevicesTxt, ETrue); for (TInt idx=0; idxiName; name.Append(KNewLine); ShowMessageL(name, EFalse); count++; } } if ( count==0 ) { // no connections! // this may be because of no devices has been discovered, // or no devices are offering the requested service. ShowMessageL(KNoConns, EFalse); } } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::SendMessageL() // // send a message to all connected devices. user will be prompted to enter // the message text. // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::SendMessageL(QString message) {/* // prompt for text TBuf msgtext; CAknTextQueryDialog * dlg = CAknTextQueryDialog::NewL(msgtext); dlg->SetMaxLength(KTwenty); dlg->SetPromptL(KMessage); dlg->ExecuteLD(R_BLUETOOTHEXAMPLE_MESSAGEINPUT);*/ //QTime time = QTime::currentTime(); TPtrC msgtext (reinterpret_cast(message.constData()), message.length()); // explicitly convert from 16bit to 8bit character set TBuf8 buf; TPtr8 msgtext8((TUint8*)buf.Ptr(), msgtext.Size()); CnvUtfConverter::ConvertFromUnicodeToUtf8(msgtext8, msgtext); TBuf msg; if ( iIsSlave ) { iStartTime.HomeTime(); // slave sending data iListener->SendDataL(msgtext8); msg.Format(KFormatStr3, &msgtext); ShowMessageL(msg, EFalse); } else { // master sending data for (TInt idx=0; idxSendDataL(msgtext8); THostName name; name=iConnectedDevices[idx]->iName; msg.Format(KFormatStr2, &name, &msgtext); ShowMessageL(msg, EFalse); } } } } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::HandleListenerDataReceivedL(TDesC& aData) // // display data the slave listener receives from the master. this is a // callback that CListener class will invoke when it receives new data. // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::HandleListenerDataReceivedL(const TDesC& aData) { // display received message TBuf msg; msg.Format(KFormatStr1, &aData); ShowMessageL(msg, EFalse); } void S60QBluetoothPrivate::HandleListenerDataSendedL() { iEndTime.HomeTime(); //TTimeIntervalSeconds seconds; TTimeIntervalMicroSeconds micro_seconds; //iEndTime.MicroSecondsFrom(iStartTime, seconds); micro_seconds = iEndTime.MicroSecondsFrom(iStartTime); //TInt time = seconds.Int(); TInt64 time = micro_seconds.Int64(); //TBuf temp = KTimeTxt(); TBuf<128> temp = KTimeTxt(); temp.AppendNum(time); temp.Append(KSecTxt); ShowMessageL(temp,EFalse); } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::HandleListenerConnectedL() // // a callback received from CListener to indicate that it has been connected to // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::HandleListenerConnectedL() { ShowMessageL(KConnMsg, ETrue); } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::HandleListenerDisconnectedL() // // a callback received from CListener to indicate that it has been disconnected // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::HandleListenerDisconnectedL() { if ( !iIsSlave ) return; // listener has already been stopped, request advertiser to stop as well iServiceAdvertiser->StopAdvertiserL(); ShowMessageL(KDisconMsg, ETrue); } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::HandleConnectorDataReceivedL(THostName aName, // TDesC& aData) // // display data the master receives from a connected slave. this is a // callback that CConnector class will invoke when it receives data from slave. // Also echo the message to other slaves. // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::HandleConnectorDataReceivedL(THostName aName, const TDesC& aData) { // display received message TBuf msg; msg.Format(KFormatStr, &aName, &aData); ShowMessageL(msg, EFalse); // echo the message to other slaves _LIT8(KSeparator, ":"); TBuf8 buf; //should use HBufC so the size will be big enough TPtr8 msgtext8((TUint8*)buf.Ptr(), aData.Size()+KSeparator().Length() + aName.Size()); CnvUtfConverter::ConvertFromUnicodeToUtf8(msgtext8, aData); //convert name to UTF8 so other slaves see //the sender name TBuf8 bufName; TPtr8 name8((TUint8*)bufName.Ptr(), aName.Size()); CnvUtfConverter::ConvertFromUnicodeToUtf8(name8, aName); //add the separator and name in the beginning; msgtext8.Insert(0, KSeparator ); msgtext8.Insert(0, name8); for (TInt idx=0; idxiName; //echo to other slaves than the sender if( name.Compare(aName) != 0) iConnectedDevices[idx]->SendDataL(msgtext8); } } } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::HandleDeviceDiscoveryCompleteL() // // a callback received from device discoverer to indicate that the device // discovery has completed. // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::HandleDeviceDiscoveryCompleteL() { iEndTime.HomeTime(); TTimeIntervalSeconds seconds; iEndTime.SecondsFrom(iStartTime, seconds); TInt time = seconds.Int(); TBuf temp = KTimeTxt(); temp.AppendNum(time); temp.Append(KSecTxt); ShowMessageL(temp,EFalse); // iterate and display found devices, if any if ( iDevDataList.Count()> 0 ) { TBuf count = KFoundTxt(); count.AppendNum( iDevDataList.Count() ); count.Append( KDevices ); ShowMessageL(count); } else { // no devices found ShowMessageL(KNoDevFound, EFalse); } } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::HandleServiceDiscoveryCompleteL() // // a callback received from service discoverer to indicate that the service // discovery has completed. // ---------------------------------------------------------------------------- void S60QBluetoothPrivate::HandleServiceDiscoveryCompleteL() { iEndTime.HomeTime(); TTimeIntervalSeconds seconds; iEndTime.SecondsFrom(iStartTime, seconds); TInt time = seconds.Int(); TBuf temp = KTimeTxt(); temp.AppendNum(time); temp.Append(KSecTxt); ShowMessageL(temp,ETrue); TInt count=0; // display devices with service we can use for ( TInt idx=0; idx<(iDevDataList.Count()); idx++ ) { TDeviceData *dev = iDevDataList[idx]; if ( dev->iDeviceServicePort>0 ) { THostName name = dev->iDeviceName; name.Append(KNewLine); ShowMessageL(name, EFalse); count++; } } if ( count==0 ) { ShowMessageL(KNoServiceFound, EFalse); } else { ShowMessageL(KServiceFound, EFalse); } } // ---------------------------------------------------------------------------- // S60QBluetoothPrivate::HasConnections() // // returns true if master has any connections to slave(s) // ---------------------------------------------------------------------------- TBool S60QBluetoothPrivate::HasConnections() { return ( iConnectedDeviceCount>0 ); } //a callback to indicate that a device has been found //main reason for this is that the UI can react so user //knows that something is going on and the app is not "frozen" void S60QBluetoothPrivate::DeviceDiscoveredL(const TDeviceData &aDevice) { TBuf name = aDevice.iDeviceName; name.Trim(); if( name.Length() == 0 ) name.Append(KDeviceWithNoName); ShowMessageL(name, EFalse); } void S60QBluetoothPrivate::ReportServiceDiscoveryErrorL(TInt aError) { TBuf discError = KServiceDiscoveryError(); discError.AppendNum(aError); QString error = QString::fromUtf16(discError.Ptr(), discError.Length()); /* iAppUi.Container().ShowMessageL(discError);*/ this->iAppUi->error(error); } //Uses the Notifier API to ask the user to turn on Bluetooth //if it's not on already. void S60QBluetoothPrivate::TurnBtOnL() { //the constant is from btnotifierapi.h which is not in all SDKs //so it's hard coded here const TUid KPowerModeSettingNotifierUid = {0x100059E2}; //const TUid KBTPowerStateNotifierUid = {0x101F808E}; //S80 and 7710 RNotifier notifier; User::LeaveIfError( notifier.Connect() ); TPckgBuf dummy(ETrue); TPckgBuf reply(EFalse); TRequestStatus stat; notifier.StartNotifierAndGetResponse(stat, KPowerModeSettingNotifierUid, dummy, reply); User::WaitForRequest(stat); notifier.CancelNotifier(KPowerModeSettingNotifierUid); notifier.Close(); } void S60QBluetoothPrivate::MbplmoError(TInt value) // Notification that an error has occured. When this is called, the current subscri... { QString message = ""; switch(value) { case KErrNotSupported : message = "The operation requested is not supported"; break; default: message = "MbplmoError:"+QString::number(value); break; } emit iAppUi->error(message); } TAny* S60QBluetoothPrivate::MbplmoExtensionInterfaceL(TUid) // Returns a null aObject if the extension is not implemented, or a pointer to anot... { //return NULL; } void S60QBluetoothPrivate::MbplmoFailedContactCounterChanged(TUint16) // Notification for the initial failed contact counter value, and whenever the fail... { } void S60QBluetoothPrivate::MbplmoLinkQualityChanged(TUint8 value) // Notification for the initial Link Quality value and whenever the Link Quality ch... { emit iAppUi->LinkQualityChanged(value); } void S60QBluetoothPrivate::MbplmoRssiChanged(TInt8 value) // Notification for the initial RSSI (received signal strengh indication) value and... { emit iAppUi->RssiChanged(value); //emit iAppUi->message("rssi"); } void S60QBluetoothPrivate::MbplmoTransmitPowerLevelChanged(TInt8 value) { emit iAppUi->PowerLevelChanged(value); } void S60QBluetoothPrivate::HandleAcceptCompleteL(TInt) { } void S60QBluetoothPrivate::HandleActivateBasebandEventNotifierCompleteL(TInt,TBTBasebandEventNotification &) { } void S60QBluetoothPrivate::HandleConnectCompleteL(TInt aErr) { /*if (aErr == KErrNone) { //TRequestStatus status; //socket.Shutdown(RSocket::ENormal, status); emit iPublicS60QBluetoothFinder->ConnectComplete(81276); // here is the place for notifying that the device has been detected } else*/ // emit iPublicS60QBluetoothFinder->ConnectComplete(aErr); } void S60QBluetoothPrivate::HandleIoctlCompleteL(TInt) { } void S60QBluetoothPrivate::HandleReceiveCompleteL(TInt aErr) { //emit iPublicS60QBluetoothFinder->ReceiveComplete(aErr); } void S60QBluetoothPrivate::HandleSendCompleteL(TInt aErr) { TTimeIntervalSeconds seconds; iEndTime.SecondsFrom(iStartTime, seconds); TInt time = seconds.Int(); TBuf temp = KTimeTxt(); temp.AppendNum(time); temp.Append(KSecTxt); ShowMessageL(temp,EFalse); //emit iPublicS60QBluetoothFinder->SendComplete(aErr); } void S60QBluetoothPrivate::HandleShutdownCompleteL(TInt aErr) { //emit iPublicS60QBluetoothFinder->ShutdownComplete(aErr); } void S60QBluetoothPrivate::MBSN_ExtensionInterfaceL(TUid,void *&) { }