X-Git-Url: http://git.maemo.org/git/?p=vicar;a=blobdiff_plain;f=src%2Fvicar-daemon%2Fsrc%2Fcallrouter.cpp;fp=src%2Fvicar-daemon%2Fsrc%2Fcallrouter.cpp;h=0000000000000000000000000000000000000000;hp=7a5d8ed39da5411f7ae368ffee598279982eda2f;hb=74800375ecf7f41e290cf7cc7fa9ee8b230be68e;hpb=89f0017e6a73945ea83247472a6fa07d6ee536b5 diff --git a/src/vicar-daemon/src/callrouter.cpp b/src/vicar-daemon/src/callrouter.cpp deleted file mode 100755 index 7a5d8ed..0000000 --- a/src/vicar-daemon/src/callrouter.cpp +++ /dev/null @@ -1,496 +0,0 @@ -/* -@version: 0.6 -@author: Sudheer K. -@license: GNU General Public License -*/ - -#include "callrouter.h" -#include "vicardbusadaptor.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class CallRouterPrivate -{ -public: - CallRouterPrivate(CallRouter * p) : - databaseUtility(new DatabaseUtility(p)), - dbusAdaptor(new VicarDbusAdaptor(p)), - dbusUtility(new DbusUtility(p)), - gconfUtility(new GConfUtility(p)), - tpUtility(new TelepathyUtility(p)), - parent(p) - { - Q_ASSERT(0 != dbusAdaptor); - //Do not open here - Unable to capture changes to DB if it is open too early and closed late. - //databaseUtility->openDatabase(); - } - - ~CallRouterPrivate() - { - qDebug() << "VICaR: Call Router Destructing"; - //databaseUtility->closeDatabase(); - } - - DatabaseUtility *databaseUtility; - VicarDbusAdaptor * dbusAdaptor; - DbusUtility * dbusUtility; - GConfUtility * gconfUtility; - TelepathyUtility *tpUtility; - QString strLastDialedNumber; - QString strLastDTMFCode; - org::maemo::vicar::Profile *currentProfile; - CallRouter * const parent; -}; - -// --------------------------------------------------------------------------- - -CallRouter::CallRouter(QObject *parent) : - QObject(parent), - d(new CallRouterPrivate(this)) -{ - Q_ASSERT(0 != d); - this->registerDBusService(); - qDebug() << "Vicar-Daemon: Registered DBus Service " << APPLICATION_DBUS_SERVICE; -} - -CallRouter::~CallRouter(){ -} - -void CallRouter::registerDBusService(){ - //Connect to Session Bus - QDBusConnection connection = d->dbusUtility->getConnection(false); - - if (!connection.interface()->isServiceRegistered(APPLICATION_DBUS_SERVICE)){ - - if (!connection.registerService(APPLICATION_DBUS_SERVICE)) { - qDebug() << "Vicar-Daemon: " << d->dbusUtility->getErrorMessage(); - exit(1); - } - } - - if (!connection.registerObject(APPLICATION_DBUS_PATH, this, QDBusConnection::ExportAdaptors)) { - qDebug() << "Vicar-Daemon: " << d->dbusUtility->getErrorMessage(); - exit(2); - } - -} - - -void CallRouter::unregisterDBusService(){ - - //Disconnect from Session bus - QDBusConnection connection = d->dbusUtility->getConnection(false); - - connection.unregisterObject(APPLICATION_DBUS_PATH,QDBusConnection::UnregisterTree); - - if (!connection.unregisterService(APPLICATION_DBUS_SERVICE)) { - qDebug() << "Vicar-Daemon: " << d->dbusUtility->getErrorMessage(); - exit(3); - } - -} - -QString CallRouter::callViaCallingCard(QString strDestinationNumber){ - - d->currentProfile = new org::maemo::vicar::Profile(); - d->currentProfile->profileID = 0; - - d->databaseUtility->openDatabase(); - bool result = d->databaseUtility->findProfileByNumber(strDestinationNumber,d->currentProfile); - - QString strErrorMessage; - if (!result){ - strErrorMessage = QString("Vicar-Daemon: Error finding VICaR profile. %1").arg(d->databaseUtility->lastError().text()); - } - else if (d->currentProfile->profileID == 0){ - bool routeOnDefault = d->gconfUtility->getGconfValueBoolean("route_on_default"); - if (routeOnDefault){ - qDebug() << "Vicar-Daemon: Routing directly as per configuration"; - this->placeCall(strDestinationNumber); - } - else{ - qDebug() << "Vicar-Daemon: No profile found. Stopping.."; - strErrorMessage = "Vicar: No routing profile defined for this number."; - d->dbusUtility->displayNotification(strErrorMessage ); - } - } - else{ - //Now call the calling card number. This is generally a local and/or tollfree number - QString strCallingCardNumber = d->currentProfile->gatewayNumber; - qDebug() << "Vicar-Daemon: Initiating call to "<< strCallingCardNumber; - bool status = this->placeCall(strCallingCardNumber); - d->strLastDialedNumber = strDestinationNumber; - - QString strUserMessage; - - if (status){ - qDebug() << "Vicar-Daemon: Call initiated successfully. Connecting DBus slot for audio connection monitor"; - startCallStatusMonitors(); - } - else { - strUserMessage = QString("Unable to initiate new call to ").append(strCallingCardNumber); - strErrorMessage = d->dbusUtility->getErrorMessage(); - qDebug() << "Vicar-Daemon: " << strErrorMessage; - d->strLastDialedNumber.clear(); - delete d->currentProfile; - d->currentProfile = 0; - } - d->dbusUtility->displayNotification(strUserMessage); - } - - d->databaseUtility->closeDatabase(); - return strErrorMessage; -} - -bool CallRouter::placeCall(QString number){ - - QList argsToSend; - argsToSend.append(number); - argsToSend.append(0); - - bool status = d->dbusUtility->sendMethodCall(CSD_SERVICE, - CSD_CALL_PATH, - CSD_CALL_INTERFACE, - QString("CreateWith"),argsToSend); - return status; - -} - -void CallRouter::startCallStatusMonitors(){ - /* Declare the slot to be executed when a call is picked up by other party (Audio connection established). - We need this to confirm whether a call went though successfully. - */ - - QDBusConnection connection = d->dbusUtility->getConnection(); - - bool success = connection.connect(QString(""), - CSD_CALL_INSTANCE_PATH, - CSD_CALL_INSTANCE_INTERFACE, - QString("AudioConnect"),this, - SLOT(sendNumberAsDTMFCode(const QDBusMessage&))); - - if (success){ - qDebug() << "Vicar-Daemon: Successfully connected to Dbus signal AudioConnect in interface "<< CSD_CALL_INSTANCE_INTERFACE; - } - else{ - qDebug() << "Vicar-Daemon: Failed to connect to Dbus signal AudioConnect in interface "<< CSD_CALL_INSTANCE_INTERFACE; - qDebug() <<"Vicar-Daemon: DBus Error: "<< d->dbusUtility->getErrorMessage(); - } - - - /* Declare the slot to be executed when the DTMF code is sent. - */ - - success = connection.connect(QString(""), - CSD_CALL_INSTANCE_PATH, - CSD_CALL_INSTANCE_INTERFACE, - QString("StoppedDTMF"),this, - SLOT(displayDTMFConfirmation())); - - if (success){ - qDebug() << "Vicar-Daemon: Successfully connected to Dbus signal StoppedDTMF in interface "<< CSD_CALL_INSTANCE_INTERFACE; - } - else{ - qDebug() << "Vicar-Daemon: Failed to connect to Dbus signal StoppedDTMF in interface "<< CSD_CALL_INSTANCE_INTERFACE; - qDebug() <<"Vicar-Daemon: DBus Error: "<< d->dbusUtility->getErrorMessage(); - } - - - /* Declare the slot to be executed when the call is terminated (due to connection errors etc). - We need this to avoid sending DTMF code on wrong calls. - */ - - success = connection.connect(QString(""), - CSD_CALL_INSTANCE_PATH, - CSD_CALL_INSTANCE_INTERFACE, - QString("Terminated"),this, - SLOT(stopCallStatusMonitors())); - - if (success){ - qDebug() << "Vicar-Daemon: Successfully connected to Dbus signal Terminated in interface "<< CSD_CALL_INSTANCE_INTERFACE; - } - else{ - qDebug() << "Vicar-Daemon: Failed to connect to Dbus signal Terminated in interface "<< CSD_CALL_INSTANCE_INTERFACE; - qDebug() <<"Vicar-Daemon: DBus Error: "<< d->dbusUtility->getErrorMessage(); - } - - /* Declare the slot to be executed when a call is received - (before we can place the call to calling card number). - It is extremely rare that somebody should get a call within these few seconds. - In any case, we need this to avoid sending DTMF code on the received call. - - Btw - I don't care for the incoming number here. If anyone is calling the user before we can send DTMF code, - then we stop sending the DTMF code even if user does not respond to the call. - */ - - success = connection.connect(QString(""), - CSD_CALL_PATH, - CSD_CALL_INTERFACE, - QString("Coming"),this, - SLOT(stopCallStatusMonitors())); - - if (success){ - qDebug() << "Vicar-Daemon: Successfully connected to Dbus signal Coming in interface" << CSD_CALL_INTERFACE; - } - else{ - qDebug() << "Vicar-Daemon: Failed to connect to Dbus signal Coming in interface" << CSD_CALL_INTERFACE; - qDebug() <<"Vicar-Daemon: DBus Error: "<< d->dbusUtility->getErrorMessage(); - } -} - -void CallRouter::stopCallStatusMonitors(){ - - d->strLastDTMFCode.clear(); - d->strLastDialedNumber.clear(); - delete d->currentProfile; - d->currentProfile = 0; - - QDBusConnection connection = d->dbusUtility->getConnection(); - - // Disconnect the slot for audio connection status - bool status = connection.disconnect(QString(""), - CSD_CALL_INSTANCE_PATH, - CSD_CALL_INSTANCE_INTERFACE, - QString("AudioConnect"),this, - SLOT(sendNumberAsDTMFCode(const QDBusMessage&))); - - if (status){ - qDebug() << "Vicar-Daemon: Successfully disconnected from Dbus signal AudioConnect in interface "<< CSD_CALL_INSTANCE_INTERFACE; - } - else{ - qDebug() << "Vicar-Daemon: Failed to disconnect from Dbus signal AudioConnect in interface "<< CSD_CALL_INSTANCE_INTERFACE; - qDebug() <<"Vicar-Daemon: DBus Error: "<< d->dbusUtility->getErrorMessage(); - } - - // Disconnect the slot for monitoring DTMF completion - status = connection.disconnect(QString(""), - CSD_CALL_INSTANCE_PATH, - CSD_CALL_INSTANCE_INTERFACE, - QString("StoppedDTMF"),this, - SLOT(displayDTMFConfirmation())); - - if (status){ - qDebug() << "Vicar-Daemon: Successfully disconnected from Dbus signal StoppedDTMF in interface "<< CSD_CALL_INSTANCE_INTERFACE; - } - else{ - qDebug() << "Vicar-Daemon: Failed to disconnect from Dbus signal StoppedDTMF in interface "<< CSD_CALL_INSTANCE_INTERFACE; - qDebug() <<"Vicar-Daemon: DBus Error: "<< d->dbusUtility->getErrorMessage(); - } - - - // Disconnect the slot for monitoring terminated calls - status = connection.disconnect(QString(""), - CSD_CALL_INSTANCE_PATH, - CSD_CALL_INSTANCE_INTERFACE, - QString("Terminated"),this, - SLOT(stopCallStatusMonitors())); - - if (status){ - qDebug() << "Vicar-Daemon: Successfully disconnected from Dbus signal Terminated in interface "<< CSD_CALL_INSTANCE_INTERFACE; - } - else{ - qDebug() << "Vicar-Daemon: Failed to disconnect from Dbus signal Terminated in interface "<< CSD_CALL_INSTANCE_INTERFACE; - qDebug() <<"Vicar-Daemon: DBus Error: "<< d->dbusUtility->getErrorMessage(); - } - - // Disconnect the slot for monitoring incoming calls - status = connection.disconnect(QString(""), - CSD_CALL_PATH, - CSD_CALL_INTERFACE, - QString("Coming"),this, - SLOT(stopCallStatusMonitors())); - - if (status){ - qDebug() << "Vicar-Daemon: Successfully disconnected from Dbus signal Coming in interface" << CSD_CALL_INTERFACE; - } - else{ - qDebug() << "Vicar-Daemon: Failed to disconnect from Dbus signal Coming in interface" << CSD_CALL_INTERFACE; - qDebug() <<"Vicar-Daemon: DBus Error: "<< d->dbusUtility->getErrorMessage(); - } -} - -void CallRouter::sendNumberAsDTMFCode(const QDBusMessage& dbusMessage){ - - if (!d->strLastDialedNumber.isEmpty() && d->currentProfile != 0){ - //Verify whether we have the last dialed number available - - QList listArguments = dbusMessage.arguments(); - bool audioConnected = listArguments.first().toBool(); - - if (audioConnected){ - // Now that the call to Calling card number is successful. We can send the original number as DTMF tones - QString strDTMFCode = convertToDTMFCode(d->strLastDialedNumber); - - qDebug() << "Vicar-Daemon: Audio connection established. Sending DTMF code "<< strDTMFCode; - - - QList argsToSend; - argsToSend.append(strDTMFCode); - bool status = d->dbusUtility->sendMethodCall(CSD_SERVICE, - CSD_CALL_PATH, - CSD_CALL_INTERFACE, - QString("SendDTMF"),argsToSend); - - if (status){ - qDebug() << "Vicar-Daemon: Sending " << strDTMFCode << " as DTMF code."; - d->strLastDTMFCode = strDTMFCode; - } - else{ - qDebug() << "Vicar-Daemon: Unable to send DTMF code."; - } - } - else{ - qDebug() << "Vicar-Daemon: Audio not yet connected."; - } - } - else - { - qDebug() << "Vicar-Daemon: Last dialed number is empty."; - } -} - -void CallRouter::displayDTMFConfirmation(){ - //This slot is called when the all the DTMF tones are sent (i.e StoppedDTMF signal is emitted) - //Just display confirmation message and cleanup - - - if (!d->strLastDTMFCode.isEmpty()){ - QString strMessage = d->strLastDTMFCode.append(" sent as DTMF code"); - d->dbusUtility->displayNotification(strMessage); - qDebug() << "Vicar-Daemon: "<< d->strLastDTMFCode << " sent as DTMF code."; - } - - /* - Connecting and Disconnecting from/to DBus signal for each international call - may not be the most efficient way of handling this. But we need to make sure - that the DTMF codes are sent only for the calls placed by this app (i.e calls to Calling card number). - */ - - qDebug() << "Vicar-Daemon: Now disconnecting from call status monitors.."; - stopCallStatusMonitors(); -} - -QString CallRouter::convertToDTMFCode(QString strNumber){ - QString strDTMFCode; - - if (!strNumber.isEmpty()){ - //int intDTMFDelay = 1; - - //Add the prefix p so that there is some delay after the call is picked up by the automated system to send DTMF tones. - //strDTMFCode = QString("").fill('p',intDTMFDelay); - strDTMFCode = ""; - - //Now check whether we need a prefix - QString strDTMFPrefix = d->currentProfile->dtmfPrefix; - - if (!strDTMFPrefix.isEmpty()){ - strDTMFCode = strDTMFCode.append(strDTMFPrefix); - } - - //Get the format required by calling card from coniguration - QString qstrDTMFFormat = d->currentProfile->dtmfFormat; - if (qstrDTMFFormat.isEmpty()) qstrDTMFFormat = ""; - - /* Replace 00 (international dialing code) at the beginning - and also replace any character other than the numbers 0-9 and p. - */ - QRegExp regexp = QRegExp("(^0{2})|[^0-9p]"); - strNumber = strNumber.replace(regexp,""); - - /* Now we have a clean number with only country code, area code and phone number, - lets convert it to the calling card friendly format - */ - if (qstrDTMFFormat.startsWith("+")){ - strDTMFCode = strDTMFCode.append("+"); - } - else if (qstrDTMFFormat.startsWith("00")){ - strDTMFCode = strDTMFCode.append("00"); - } - else if (qstrDTMFFormat.startsWith("011")){ - strDTMFCode = strDTMFCode.append("011"); - } - - strDTMFCode = strDTMFCode.append(strNumber); - - //Now check whether we need a suffix - QString strDTMFSuffix = d->currentProfile->dtmfSuffix; - if (!strDTMFSuffix.isEmpty()){ - strDTMFCode = strDTMFCode.append(strDTMFSuffix); - } - } - - return strDTMFCode; -} - -//DBus Method used by external applications to check whether VICaR is enabled and running -bool CallRouter::isRunning(){ - - return true; - - //Verify Whether VICaR telepathy account is online - /* - if (d->tpUtility->getAccountStatus() == "Connected"){ - return true; - } - else{ - return false; - } - */ -} - -//DBus Method used by external applications to call via VICaR -QString CallRouter::callInternationalNumber(const QString& strDestinationNumber){ - - QString strErrorMessage; - - qDebug() << "Vicar-Daemon: New call requested by external application. Destination number is " << strDestinationNumber; - - if (isValidPhoneNumber(strDestinationNumber)){ - - //Remove spaces in the phone number before using - QString numberWithoutSpaces = QString(strDestinationNumber).remove(" "); - - strErrorMessage = this->callViaCallingCard(numberWithoutSpaces); - } - else{ - strErrorMessage = QString("Vicar-Daemon: %1 is not a valid number").arg(strDestinationNumber); - if (strDestinationNumber != "publish" && strDestinationNumber != "subscribe"){ - d->dbusUtility->displayNotification(QString("Vicar: %1 is not a valid number").arg(strDestinationNumber)); - } - } - - qDebug() << strErrorMessage; - - if (strErrorMessage.isEmpty()){ - return QString("Success"); - } - else{ - return strErrorMessage; - } - } - -//Check whether a string is valid phone number -bool CallRouter::isValidPhoneNumber(QString strPhoneNumber){ - -/* Remove all dialble characters and space. The resulting string should be a valid number */ - QRegExp regexp = QRegExp("[p+*# ]"); - - strPhoneNumber = strPhoneNumber.replace(regexp,""); - - qDebug() << "Vicar Daemon: Cleaned up phone number is " << strPhoneNumber; - -/* Now remove all digits, the resulting string should be empty, then it is a valid number */ - regexp = QRegExp("[0-9]"); - - strPhoneNumber = strPhoneNumber.replace(regexp,""); - - bool isNumber = strPhoneNumber.isEmpty(); - return isNumber; -}