/*
-@version: 0.5
+@version: 0.6
@author: Sudheer K. <scifi1947 at gmail.com>
@license: GNU General Public License
*/
#include <QDBusMessage>
#include <QStringListIterator>
-
-//static QString strLastDialedNumber = QString();
-//static org::maemo::vicar::Profile currentProfile;
-
class CallRouterPrivate
{
public:
GConfUtility * gconfUtility;
TelepathyUtility *tpUtility;
QString strLastDialedNumber;
+ QString strLastDTMFCode;
org::maemo::vicar::Profile *currentProfile;
CallRouter * const parent;
};
{
Q_ASSERT(0 != d);
this->registerDBusService();
- qDebug() << "Registered DBus Service " << APPLICATION_DBUS_SERVICE;
+ qDebug() << "Vicar-Daemon: Registered DBus Service " << APPLICATION_DBUS_SERVICE;
}
CallRouter::~CallRouter(){
if (!connection.interface()->isServiceRegistered(APPLICATION_DBUS_SERVICE)){
if (!connection.registerService(APPLICATION_DBUS_SERVICE)) {
- qDebug() << d->dbusUtility->getErrorMessage();
+ qDebug() << "Vicar-Daemon: " << d->dbusUtility->getErrorMessage();
exit(1);
}
}
if (!connection.registerObject(APPLICATION_DBUS_PATH, this, QDBusConnection::ExportAdaptors)) {
- qDebug() << d->dbusUtility->getErrorMessage();
+ qDebug() << "Vicar-Daemon: " << d->dbusUtility->getErrorMessage();
exit(2);
}
connection.unregisterObject(APPLICATION_DBUS_PATH,QDBusConnection::UnregisterTree);
if (!connection.unregisterService(APPLICATION_DBUS_SERVICE)) {
- qDebug() << d->dbusUtility->getErrorMessage();
+ qDebug() << "Vicar-Daemon: " << d->dbusUtility->getErrorMessage();
exit(3);
}
QString strErrorMessage;
if (!result){
- strErrorMessage = QString("Error finding VICaR profile. %1").arg(d->databaseUtility->lastError().text());
+ 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() << "Routing directly as per configuration";
+ qDebug() << "Vicar-Daemon: Routing directly as per configuration";
this->placeCall(strDestinationNumber);
}
else{
- qDebug() << "No profile found. Stopping..";
- strErrorMessage = "VICaR: No routing profile defined for this number.";
+ 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() << "Initiating call to "<< strCallingCardNumber;
+ qDebug() << "Vicar-Daemon: Initiating call to "<< strCallingCardNumber;
bool status = this->placeCall(strCallingCardNumber);
d->strLastDialedNumber = strDestinationNumber;
QString strUserMessage;
if (status){
- qDebug() << "Call initiated successfully. Connecting DBus slot for audio connection monitor";
+ 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() << strErrorMessage;
+ qDebug() << "Vicar-Daemon: " << strErrorMessage;
d->strLastDialedNumber.clear();
delete d->currentProfile;
d->currentProfile = 0;
SLOT(sendNumberAsDTMFCode(const QDBusMessage&)));
if (success){
- qDebug() << "Successfully connected to Dbus signal AudioConnect in interface "<< CSD_CALL_INSTANCE_INTERFACE;
+ 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() << "Failed to connect to Dbus signal AudioConnect in interface "<< CSD_CALL_INSTANCE_INTERFACE;
- qDebug() <<"DBus Error: "<< d->dbusUtility->getErrorMessage();
+ 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.
*/
SLOT(stopCallStatusMonitors()));
if (success){
- qDebug() << "Successfully connected to Dbus signal Terminated in interface "<< CSD_CALL_INSTANCE_INTERFACE;
+ qDebug() << "Vicar-Daemon: Successfully connected to Dbus signal Terminated in interface "<< CSD_CALL_INSTANCE_INTERFACE;
}
else{
- qDebug() << "Failed to connect to Dbus signal Terminated in interface "<< CSD_CALL_INSTANCE_INTERFACE;
- qDebug() <<"DBus Error: "<< d->dbusUtility->getErrorMessage();
+ 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
SLOT(stopCallStatusMonitors()));
if (success){
- qDebug() << "Successfully connected to Dbus signal Coming in interface" << CSD_CALL_INTERFACE;
+ qDebug() << "Vicar-Daemon: Successfully connected to Dbus signal Coming in interface" << CSD_CALL_INTERFACE;
}
else{
- qDebug() << "Failed to connect to Dbus signal Coming in interface" << CSD_CALL_INTERFACE;
- qDebug() <<"DBus Error: "<< d->dbusUtility->getErrorMessage();
+ 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;
SLOT(sendNumberAsDTMFCode(const QDBusMessage&)));
if (status){
- qDebug() << "Successfully disconnected from Dbus signal AudioConnect in interface "<< CSD_CALL_INSTANCE_INTERFACE;
+ 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() << "Failed to disconnect from Dbus signal AudioConnect in interface "<< CSD_CALL_INSTANCE_INTERFACE;
- qDebug() <<"DBus Error: "<< d->dbusUtility->getErrorMessage();
+ 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,
SLOT(stopCallStatusMonitors()));
if (status){
- qDebug() << "Successfully disconnected from Dbus signal Terminated in interface "<< CSD_CALL_INSTANCE_INTERFACE;
+ qDebug() << "Vicar-Daemon: Successfully disconnected from Dbus signal Terminated in interface "<< CSD_CALL_INSTANCE_INTERFACE;
}
else{
- qDebug() << "Failed to disconnect from Dbus signal Terminated in interface "<< CSD_CALL_INSTANCE_INTERFACE;
- qDebug() <<"DBus Error: "<< d->dbusUtility->getErrorMessage();
+ 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
SLOT(stopCallStatusMonitors()));
if (status){
- qDebug() << "Successfully disconnected from Dbus signal Coming in interface" << CSD_CALL_INTERFACE;
+ qDebug() << "Vicar-Daemon: Successfully disconnected from Dbus signal Coming in interface" << CSD_CALL_INTERFACE;
}
else{
- qDebug() << "Failed to disconnect from Dbus signal Coming in interface" << CSD_CALL_INTERFACE;
- qDebug() <<"DBus Error: "<< d->dbusUtility->getErrorMessage();
+ qDebug() << "Vicar-Daemon: Failed to disconnect from Dbus signal Coming in interface" << CSD_CALL_INTERFACE;
+ qDebug() <<"Vicar-Daemon: DBus Error: "<< d->dbusUtility->getErrorMessage();
}
}
// 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() << "Audio connection established. Sending DTMF code "<< strDTMFCode;
+ 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){
- QString strMessage = strDTMFCode.append(" sent as DTMF code");
- qDebug() << strMessage;
- d->dbusUtility->displayNotification(strMessage);
+ qDebug() << "Vicar-Daemon: Sending " << strDTMFCode << " as DTMF code.";
+ d->strLastDTMFCode = strDTMFCode;
}
else{
- qDebug() << "Unable to send DTMF code.";
+ qDebug() << "Vicar-Daemon: Unable to send 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() << "Now disconnecting from call status monitors..";
- stopCallStatusMonitors();
-
- d->strLastDialedNumber.clear();
- delete d->currentProfile;
- d->currentProfile = 0;
}
else{
- qDebug() << "Audio not yet connected.";
+ qDebug() << "Vicar-Daemon: Audio not yet connected.";
}
}
else
{
- qDebug() << "Last dialed number is empty.";
+ 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;
+ //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 = QString("").fill('p',intDTMFDelay);
+ strDTMFCode = "";
//Now check whether we need a prefix
QString strDTMFPrefix = d->currentProfile->dtmfPrefix;
//DBus Method used by external applications to call via VICaR
QString CallRouter::callInternationalNumber(const QString& strDestinationNumber){
- qDebug() << "New call requested by external application. Destination number is " << strDestinationNumber;
- QString strErrorMessage = this->callViaCallingCard(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 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;
+}