3 @author: Sudheer K. <scifi1947 at gmail.com>
4 @license: GNU General Public License
6 Based on Telepathy-SNOM with copyright notice below.
10 * Telepathy SNOM VoIP phone connection manager
11 * Copyright (C) 2006 by basyskom GmbH
12 * @author Tobias Hunger <info@basyskom.de>
14 * This library is free software; you can redisQObject::tribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License version 2.1 as published by the Free Software Foundation.
18 * This library is disQObject::tributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, write to the
25 * Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "connection.h"
30 #include "connectionadaptor.h"
31 #include "connectioninterfacerequestsadaptor.h"
32 #include "connectioninterfacerequeststypes.h"
33 #include "connectioninterfacecapabilitiesadaptor.h"
34 #include "connectioninterfacecapabilitiestypes.h"
36 #include "vicarcallrouterproxy.h"
37 #include <logutility.h>
39 #include <QtCore/QDebug>
40 #include <QtCore/QCoreApplication>
41 #include <QtCore/QVariantMap>
42 #include <QDBusMessage>
48 static const QString protocol_vicar("tel");
50 static const QString connection_service_name_prefix("org.freedesktop.Telepathy.Connection.vicar." + protocol_vicar + '.');
51 static const QString connection_object_path_prefix("/org/freedesktop/Telepathy/Connection/vicar/" + protocol_vicar + '/');
52 static const QString requests_interface("org.freedesktop.Telepathy.Connection.Interface.Requests");
55 using namespace org::maemo;
58 class ConnectionPrivate
61 ConnectionPrivate(Connection * p,
62 const QString & acc) :
64 connection_status(Connection::Disconnected),
65 adaptor(new ConnectionAdaptor(p)),
66 connIfaceReqsAdaptor(new ConnectionInterfaceRequestsAdaptor(p)),
67 logUtility(new LogUtility("/var/log/vicar/vicar.log",p)),
70 Q_ASSERT(0 != adaptor);
75 qDebug() << "VICaR Connection: Connection Destructing";
78 const QString account;
80 Connection::Status connection_status;
81 ConnectionAdaptor * adaptor;
82 ConnectionInterfaceRequestsAdaptor * connIfaceReqsAdaptor;
83 LogUtility * const logUtility;
84 Connection * const parent;
87 // ---------------------------------------------------------------------------
89 Connection::Connection(const QString & account,
92 d(new ConnectionPrivate(this, account))
96 strMessage = "DEBUG: In Connection Constructor";
97 qDebug() << strMessage;
98 d->logUtility->logMessage(strMessage);
101 Q_ASSERT(!account.isEmpty());
103 /* -- Set the Dynamic property "Interfaces" ---
105 Apparently it is not sufficient to implement an additional interface like Conn.I.Requests.
106 We have to assign the list of additional interfaces to the DBus Property Interfaces.
108 The actual DBus property "Interfaces" is declared in ConnectionAdaptor class,
109 which is our Connection Interface implementation.
112 QStringList interfaces = QStringList(requests_interface);
113 this->setProperty("Interfaces",interfaces);
115 // Set the Dynamic property "HasImmortalHandles" to true as per telepathy Connection spec 0.21.6
116 //The handles for vicar connection are expected to last throughout the lifetime of the connection
117 this->setProperty("HasImmortalHandles",true);
119 this->setProperty("Status",org::freedesktop::Telepathy::CONNECTION_STATUS_CONNECTED);
120 this->setProperty("SelfHandle",org::freedesktop::Telepathy::HANDLE_TYPE_CONTACT);
122 //Set the property RequestableChannelClasses
123 org::freedesktop::Telepathy::RequestableChannelClassList requestableChannelClasses;
125 uint targetHandleType(1);
127 org::freedesktop::Telepathy::RequestableChannelClass requestableChannelClass1;
128 requestableChannelClass1.fixedProperties.insert("org.freedesktop.Telepathy.Channel.TargetHandleType",targetHandleType);
129 requestableChannelClass1.fixedProperties.insert("org.freedesktop.Telepathy.Channel.ChannelType","org.freedesktop.Telepathy.Channel.Type.StreamedMedia");
131 requestableChannelClass1.allowedProperties.append("org.freedesktop.Telepathy.Channel.TargetHandle");
132 requestableChannelClass1.allowedProperties.append("org.freedesktop.Telepathy.Channel.Type.StreamedMedia.InitialAudio");
134 requestableChannelClasses.append(requestableChannelClass1);
136 org::freedesktop::Telepathy::RequestableChannelClass requestableChannelClass2;
137 requestableChannelClass2.fixedProperties.insert("org.freedesktop.Telepathy.Channel.TargetHandleType",targetHandleType);
138 requestableChannelClass2.fixedProperties.insert("org.freedesktop.Telepathy.Channel.ChannelType","org.freedesktop.Telepathy.Channel.Type.StreamedMedia");
140 requestableChannelClass2.allowedProperties.append("com.nokia.Telepathy.Channel.Interface.Conference.InitialMembers");
141 requestableChannelClass2.allowedProperties.append("org.freedesktop.Telepathy.Channel.TargetHandleType");
142 requestableChannelClass2.allowedProperties.append("org.freedesktop.Telepathy.Channel.Type.StreamedMedia.InitialAudio");
144 requestableChannelClasses.append(requestableChannelClass2);
147 this->setProperty("RequestableChannelClasses",QVariant::fromValue(requestableChannelClasses));
149 //Set the property Channels
150 org::freedesktop::Telepathy::ChannelDetailsList channelDetails;
151 this->setProperty("Channels",QVariant::fromValue(channelDetails));
153 //Set the connection status to Connected (default for Vicar)
154 d->connection_status = Connection::Connected;
157 strMessage = "VICaR Connection: Connection set up.";
159 qDebug() << strMessage;
160 d->logUtility->logMessage(strMessage);
163 Connection::~Connection()
165 qDebug() << "VICaR Connection: Connection closed.";
169 bool Connection::registerObject()
173 if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName())){
174 if (!QDBusConnection::sessionBus().registerService(serviceName()))
176 strMessage = "VICaR Connection: Problem registering connection service:" + serviceName();
177 qDebug() << strMessage;
178 d->logUtility->logMessage(strMessage);
182 if (!QDBusConnection::sessionBus().registerObject(objectPath().path(),
185 strMessage = "VICaR Connection: Problem registering object path:" + objectPath().path();
186 qDebug() << strMessage;
187 d->logUtility->logMessage(strMessage);
192 strMessage = "VICaR Connection: " + serviceName()+" is already registered on DBus";
193 qDebug() << strMessage;
194 d->logUtility->logMessage(strMessage);
199 void Connection::unregisterObject()
201 QString strMessage = "VICaR Connection: Unregistering Connection object from DBus";
202 qDebug() << strMessage;
203 d->logUtility->logMessage(strMessage);
204 QDBusConnection::sessionBus().unregisterObject(objectPath().path());
205 QDBusConnection::sessionBus().unregisterService(serviceName());
208 QString Connection::name() const
210 return QString("vicar");
214 QString Connection::serviceName() const
215 { return connection_service_name_prefix + name(); }
217 QDBusObjectPath Connection::objectPath() const
218 { return QDBusObjectPath(connection_object_path_prefix + name()); }
221 //org.freedesktop.Telepathy.Connection
222 void Connection::Connect()
225 Since this is not a "real" Telepathy Connection to a SIP, Chat server,
226 I am not connecting to anything.
228 QString strMessage = "VICaR Connection: Changing status to Connected...";
229 qDebug() << strMessage;
230 d->logUtility->logMessage(strMessage);
231 d->connection_status = Connection::Connected;
233 //Let all the Telepathy clients know that connection status has changed
234 strMessage = "VICaR Connection: Emitting StatusChanged.";
235 qDebug() << strMessage;
236 d->logUtility->logMessage(strMessage);
237 emit StatusChanged(d->connection_status, ReasonRequested);
240 void Connection::Disconnect()
242 QString strMessage = "VICaR Connection: Changing status to Disconnected...";
243 qDebug() << strMessage;
244 d->logUtility->logMessage(strMessage);
245 //We don't have any Handles to release here. So just change the status to Disconnected
246 d->connection_status = Connection::Disconnected;
248 strMessage = "VICaR Connection: Emitting StatusChanged";
249 qDebug() << strMessage;
250 d->logUtility->logMessage(strMessage);
251 emit StatusChanged(d->connection_status, ReasonRequested);
253 //As per Telepathy specfication, on disconnect we need to unregister from Dbus and destroy the object.
258 QStringList Connection::GetInterfaces()
261 if (d->connection_status != Connected)
263 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
264 "VICaR - Unable to get Interfaces List. The connection is no longer available.");
267 result <<requests_interface;
271 QString Connection::GetProtocol()
272 { return protocol_vicar; }
274 uint Connection::GetStatus()
275 { return static_cast<uint>(d->connection_status); }
277 uint Connection::GetSelfHandle()
279 QString strMessage = "VICaR Connection: GetSelfHandle";
280 qDebug() << strMessage;
281 d->logUtility->logMessage(strMessage);
282 if (d->connection_status != Connected)
284 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
285 "VICaR - Unable to get Self Handle. The connection is no longer available.");
286 strMessage = "VICaR Connection: NOT CONNECTED when requesting selfhandle!";
287 qDebug() << strMessage;
288 d->logUtility->logMessage(strMessage);
292 //WARNING: Incomplete implemenation
294 strMessage = "VICaR Connection: Returning Handle " + QString(handle) + "as self handle.";
295 qDebug() << strMessage;
296 d->logUtility->logMessage(strMessage);
300 QList<uint> Connection::RequestHandles(uint handle_type,
301 const QStringList & names)
307 if (d->connection_status != Connected)
309 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
310 "VICaR - Unable to process handle request. The connection is no longer available.");
313 if (handle_type != HandleContact)
315 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
316 "VICaR - Supports handles of type Contact only.");
320 //WARNING: Incomplete implementation. Create a handle and return the value here.
324 void Connection::HoldHandles(const uint handle_type, const QList<uint> &handles)
327 QString strMessage = "VICaR Connection: HoldHandles.";
328 qDebug() << strMessage;
329 d->logUtility->logMessage(strMessage);
330 if (d->connection_status != Connected)
333 strMessage = "VICaR Connection: HoldHandles - Not Connected.";
334 qDebug() << strMessage;
335 d->logUtility->logMessage(strMessage);
337 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
338 "VICaR - Unable to process handle request. The connection is no longer available.");
341 if (handle_type != HandleContact)
344 strMessage = "VICaR Connection: HoldHandles - Invalid Handle Type.";
345 qDebug() << strMessage;
346 d->logUtility->logMessage(strMessage);
348 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
349 "VICaR - Supports handles of type Contact only.");
353 //WARNING: Incomplete implementation
356 QStringList Connection::InspectHandles(const uint handle_type,
357 const QList<uint> &handles)
360 QStringList handlesList;
362 QString strMessage = "VICaR Connection: InspectHandles.";
363 qDebug() << strMessage;
364 d->logUtility->logMessage(strMessage);
367 if (d->connection_status != Connected)
369 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
370 "VICaR - Unable to process handle request. The connection is no longer available.");
373 if (handle_type != HandleContact)
375 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
376 "VICaR - Supports handles of type Contact only.");
381 for (int i = 0 ; i < handles.length(); i++) {
382 handle = handles.at(i);
383 strMessage = "VICaR Connection: Inspecting handle "+QString(handle);
384 qDebug() << strMessage;
385 d->logUtility->logMessage(strMessage);
386 handlesList.append(QString(handle));
389 //WARNING: Incomplete implementation
393 void Connection::ReleaseHandles(const uint handle_type, const QList<uint> &handles)
397 if (d->connection_status != Connected)
399 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
400 "VICaR - Unable to release handle. The connection is no longer available.");
401 strMessage = "VICaR Connection: Releasing Handle while connection is no longer connected.";
402 qDebug() << strMessage;
403 d->logUtility->logMessage(strMessage);
406 if (handle_type != HandleContact)
408 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
409 "VICaR - Supports handles of type Contact only.");
410 strMessage = "VICaR Connection: Trying to release a Handle that is not a contact.";
411 qDebug() << strMessage;
412 d->logUtility->logMessage(strMessage);
416 //WARNING: Incomplete implementation
419 org::freedesktop::Telepathy::ChannelInfoList Connection::ListChannels()
421 org::freedesktop::Telepathy::ChannelInfoList result;
422 if (d->connection_status != Connected)
424 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
425 "VICaR - Unable to list channels. The connection is no longer available.");
429 //WARNING: Incomplete implementation
430 //Btw - We never have any channels :)
435 QDBusObjectPath Connection::RequestChannel(const QString &type,
436 uint handle_type, uint handle,
437 bool suppress_handler)
440 Q_UNUSED(suppress_handler);
441 //This method is deprecated and no longer used as per latest Telepathy spec
443 if (type != QString("org.freedesktop.Telepathy.Channel.Type.StreamedMedia"))
445 sendErrorReply("org.freedesktop.Telepathy.Error.NotImplemented",
446 "VICaR Connection: Failed to create channel: Channel type not implemented.");
447 return QDBusObjectPath();
450 if (handle_type != HandleContact )
452 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidHandle",
453 "VICaR Connection: Failed to create channel: Handle type not supported.");
454 return QDBusObjectPath();
457 if (d->connection_status != Connected)
459 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
460 "VICaR Connection: Failed to create channel: Connection is Disconnected.");
461 return QDBusObjectPath();
464 //WARNING: Incomplete implementation, we are not creating any channels here at all.
465 QDBusObjectPath channel_path;
469 //org.freedesktop.Telepathy.Connection.Interface.Requests
470 QDBusObjectPath Connection::CreateChannel(const QVariantMap &request,
471 QVariantMap &channel_properties)
473 Q_UNUSED(channel_properties);
474 Q_ASSERT(!request.isEmpty());
476 strMessage = "VICaR Connection: CreateChannel";
477 qDebug() << strMessage;
478 d->logUtility->logMessage(strMessage);
479 qDebug() << " Request details are: "<< request;
481 //Ideally we need to emit NewChannels signal here, but since we are not creating any channels we ignore it
483 //WARNING: VICaR - Specific implementation
484 return processChannel(request);
488 bool Connection::EnsureChannel(const QVariantMap &request,
489 QDBusObjectPath &channel_object,
490 QVariantMap &channel_properties)
492 Q_UNUSED(channel_object);
493 Q_UNUSED(channel_properties);
494 Q_ASSERT(!request.isEmpty());
495 QString strMessage = "VICaR Connection: EnsureChannel";
496 qDebug() << strMessage;
497 d->logUtility->logMessage(strMessage);
498 qDebug() << " Request details are: "<< request;
500 //WARNING: Incomplete implementation
501 processChannel(request);
506 QDBusObjectPath Connection::processChannel(const QVariantMap &request){
508 QString strMessage = "VICaR Connection: ProcessChannel";
509 qDebug() << strMessage;
510 d->logUtility->logMessage(strMessage);
512 QDBusObjectPath channel_path;
514 if (!request.contains("org.freedesktop.Telepathy.Channel.TargetID")){
515 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
516 "VICaR - Invalid request. TargetID (Phone Number) not included.");
520 QVariant vNumber = request.value("org.freedesktop.Telepathy.Channel.TargetID");
521 if (!vNumber.isValid()){
522 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
523 "VICaR - Invalid request. Phone Number is not valid.");
526 QString strNumber = vNumber.toString();
527 if (strNumber.isEmpty()){
528 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
529 "VICaR - Invalid request. Phone Number is empty.");
532 else if (strNumber == "publish" || strNumber == "subscribe"){
533 //Deny the persistent Mission control requests to publish and subscribe
534 QString strError = "VICaR - Invalid request. " + strNumber + " is not supported.";
535 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
541 //Only allow requests with handle type as contact
542 QVariant vTargetHandleType = request.value("org.freedesktop.Telepathy.Channel.TargetHandleType");
543 uint intTargetHandleType = vTargetHandleType.toUInt();
544 if (intTargetHandleType != HandleContact)
546 strMessage = "VICaR - Supports handles of type Contact only. Recieved handle type ";
547 strMessage.append(vTargetHandleType.toString());
549 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
556 Send an error reply to Tp Client (Mission Control) to force it to close the active channel.
557 Once it recieves the reply, the client does not bother what we return.
561 sendErrorReply("org.freedesktop.Telepathy.Error.NotAvailable",
562 "VICaR - Creating a new channel to "+strNumber+" via Ring.");
565 //Initiate a new call to CC/Google Out/Skype-out number by requesting a new channel with Ring CM.
567 VicarCallRouterProxy *callRouter = new VicarCallRouterProxy(APPLICATION_DBUS_SERVICE,APPLICATION_DBUS_PATH,QDBusConnection::sessionBus(),this);
569 callRouter->callInternationalNumber(strNumber);
571 strMessage = "VICaR Connection: Call is processed.";
573 qDebug() << strMessage;
574 d->logUtility->logMessage(strMessage);
580 void Connection::AddClientInterest(const QStringList &tokens){
581 //WARNING: Incomplete implementation
585 strMessage = "VICaR Connection: AddClientInterest";
586 qDebug() << strMessage;
587 d->logUtility->logMessage(strMessage);
590 void Connection::RemoveClientInterest(const QStringList &tokens){
591 //WARNING: Incomplete implementation
595 strMessage = "VICaR Connection: RemoveClientInterest";
596 qDebug() << strMessage;
597 d->logUtility->logMessage(strMessage);
600 //org.freedesktop.Telepathy.Connection.Interface.Capabilities
601 org::freedesktop::Telepathy::ContactCapabilitiesList Connection::GetCapabilities(const QList<uint> &Handles){
603 org::freedesktop::Telepathy::ContactCapabilitiesList capabilities;
609 org::freedesktop::Telepathy::CapabilityPairList Connection::AdvertiseCapabilities(org::freedesktop::Telepathy::CapabilityPairList Add, const QStringList &Remove){
612 org::freedesktop::Telepathy::CapabilityPairList capabilities;