Version 0.7-0
[vicar] / src / vicar-daemon / src / callrouter.cpp
diff --git a/src/vicar-daemon/src/callrouter.cpp b/src/vicar-daemon/src/callrouter.cpp
deleted file mode 100755 (executable)
index 7a5d8ed..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
-@version: 0.6
-@author: Sudheer K. <scifi1947 at gmail.com>
-@license: GNU General Public License
-*/
-
-#include "callrouter.h"
-#include "vicardbusadaptor.h"
-#include <dbusutility.h>
-#include <gconfutility.h>
-#include <databaseutility.h>
-#include <telepathyutility.h>
-#include <QDebug>
-#include <QRegExp>
-#include <QDBusConnection>
-#include <QDBusMessage>
-#include <QStringListIterator>
-
-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<QVariant> 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<QVariant> 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<QVariant> 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 = "<Country Code><Area Code><Phone Number>";
-
-        /* 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;
-}