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>
45 #define SELF_HANDLE 1 //Any non-zero
50 static const QString protocol_vicar("tel");
52 static const QString connection_service_name_prefix("org.freedesktop.Telepathy.Connection.vicar." + protocol_vicar + '.');
53 static const QString connection_object_path_prefix("/org/freedesktop/Telepathy/Connection/vicar/" + protocol_vicar + '/');
54 static const QString requests_interface("org.freedesktop.Telepathy.Connection.Interface.Requests");
57 using namespace org::maemo;
60 class ConnectionPrivate
63 ConnectionPrivate(Connection * p,
64 const QString & acc) :
66 connection_status(Connection::Disconnected),
67 adaptor(new ConnectionAdaptor(p)),
68 connIfaceReqsAdaptor(new ConnectionInterfaceRequestsAdaptor(p)),
69 logUtility(new LogUtility(p)),
72 Q_ASSERT(0 != adaptor);
77 qDebug() << "VICaR Connection: Connection Destructing";
80 const QString account;
82 Connection::Status connection_status;
83 ConnectionAdaptor * adaptor;
84 ConnectionInterfaceRequestsAdaptor * connIfaceReqsAdaptor;
85 LogUtility * const logUtility;
86 Connection * const parent;
89 // ---------------------------------------------------------------------------
91 Connection::Connection(const QString & account,
94 d(new ConnectionPrivate(this, account))
98 strMessage = "DEBUG: In Connection Constructor";
99 d->logUtility->logMessage(strMessage);
102 Q_ASSERT(!account.isEmpty());
104 /* -- Set the Dynamic property "Interfaces" ---
106 Apparently it is not sufficient to implement an additional interface like Conn.I.Requests.
107 We have to assign the list of additional interfaces to the DBus Property Interfaces.
109 The actual DBus property "Interfaces" is declared in ConnectionAdaptor class,
110 which is our Connection Interface implementation.
113 QStringList interfaces = QStringList(requests_interface);
114 this->setProperty("Interfaces",interfaces);
116 // Set the Dynamic property "HasImmortalHandles" to true as per telepathy Connection spec 0.21.6
117 //The handles for vicar connection are expected to last throughout the lifetime of the connection
118 this->setProperty("HasImmortalHandles",true);
120 this->setProperty("Status",org::freedesktop::Telepathy::CONNECTION_STATUS_CONNECTED);
123 //this->setProperty("SelfHandle",org::freedesktop::Telepathy::HANDLE_TYPE_CONTACT);
124 uint selfHandle(SELF_HANDLE);
125 this->setProperty("SelfHandle",selfHandle);
127 strMessage = "VICaR Connection: Emitting SelfHandleChanged.";
128 d->logUtility->logMessage(strMessage);
129 emit SelfHandleChanged(selfHandle);
131 //Set the property RequestableChannelClasses
132 org::freedesktop::Telepathy::RequestableChannelClassList requestableChannelClasses;
134 uint targetHandleType(1);
136 org::freedesktop::Telepathy::RequestableChannelClass requestableChannelClass1;
137 requestableChannelClass1.fixedProperties.insert("org.freedesktop.Telepathy.Channel.TargetHandleType",targetHandleType);
138 requestableChannelClass1.fixedProperties.insert("org.freedesktop.Telepathy.Channel.ChannelType","org.freedesktop.Telepathy.Channel.Type.StreamedMedia");
140 requestableChannelClass1.allowedProperties.append("org.freedesktop.Telepathy.Channel.TargetHandle");
141 requestableChannelClass1.allowedProperties.append("org.freedesktop.Telepathy.Channel.Type.StreamedMedia.InitialAudio");
143 requestableChannelClasses.append(requestableChannelClass1);
145 org::freedesktop::Telepathy::RequestableChannelClass requestableChannelClass2;
146 requestableChannelClass2.fixedProperties.insert("org.freedesktop.Telepathy.Channel.TargetHandleType",targetHandleType);
147 requestableChannelClass2.fixedProperties.insert("org.freedesktop.Telepathy.Channel.ChannelType","org.freedesktop.Telepathy.Channel.Type.StreamedMedia");
149 requestableChannelClass2.allowedProperties.append("com.nokia.Telepathy.Channel.Interface.Conference.InitialMembers");
150 requestableChannelClass2.allowedProperties.append("org.freedesktop.Telepathy.Channel.TargetHandleType");
151 requestableChannelClass2.allowedProperties.append("org.freedesktop.Telepathy.Channel.Type.StreamedMedia.InitialAudio");
153 requestableChannelClasses.append(requestableChannelClass2);
156 this->setProperty("RequestableChannelClasses",QVariant::fromValue(requestableChannelClasses));
158 //Set the property Channels
159 org::freedesktop::Telepathy::ChannelDetailsList channelDetails;
160 this->setProperty("Channels",QVariant::fromValue(channelDetails));
162 //Set the connection status to Connected (default for Vicar)
163 d->connection_status = Connection::Connected;
166 strMessage = "VICaR Connection: Connection set up.";
168 d->logUtility->logMessage(strMessage);
171 Connection::~Connection()
173 qDebug() << "VICaR Connection: Connection closed.";
177 bool Connection::registerObject()
181 if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName())){
182 if (!QDBusConnection::sessionBus().registerService(serviceName()))
184 strMessage = "VICaR Connection: Problem registering connection service:" + serviceName();
185 d->logUtility->logMessage(strMessage);
189 if (!QDBusConnection::sessionBus().registerObject(objectPath().path(),
192 strMessage = "VICaR Connection: Problem registering object path:" + objectPath().path();
193 d->logUtility->logMessage(strMessage);
198 strMessage = "VICaR Connection: " + serviceName()+" is already registered on DBus";
199 d->logUtility->logMessage(strMessage);
204 void Connection::unregisterObject()
206 QString strMessage = "VICaR Connection: Unregistering Connection object from DBus";
207 d->logUtility->logMessage(strMessage);
208 QDBusConnection::sessionBus().unregisterObject(objectPath().path());
209 QDBusConnection::sessionBus().unregisterService(serviceName());
212 QString Connection::name() const
214 return QString("vicar");
218 QString Connection::serviceName() const
219 { return connection_service_name_prefix + name(); }
221 QDBusObjectPath Connection::objectPath() const
222 { return QDBusObjectPath(connection_object_path_prefix + name()); }
225 //org.freedesktop.Telepathy.Connection
226 void Connection::Connect()
229 Since this is not a "real" Telepathy Connection to a SIP, Chat server,
230 I am not connecting to anything.
232 QString strMessage = "VICaR Connection: Changing status to Connected...";
233 d->logUtility->logMessage(strMessage);
234 d->connection_status = Connection::Connected;
236 //Let all the Telepathy clients know that connection status has changed
237 strMessage = "VICaR Connection: Emitting StatusChanged.";
238 d->logUtility->logMessage(strMessage);
239 emit StatusChanged(d->connection_status, ReasonRequested);
242 void Connection::Disconnect()
244 QString strMessage = "VICaR Connection: Changing status to Disconnected...";
245 d->logUtility->logMessage(strMessage);
246 //We don't have any Handles to release here. So just change the status to Disconnected
247 d->connection_status = Connection::Disconnected;
249 strMessage = "VICaR Connection: Emitting StatusChanged";
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()
262 QString strMessage = "VICaR Connection: GetInterfaces.";
263 d->logUtility->logMessage(strMessage);
265 if (d->connection_status != Connected)
267 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
268 "VICaR - Unable to get Interfaces List. The connection is no longer available.");
271 result <<requests_interface;
275 QString Connection::GetProtocol()
277 QString strMessage = "VICaR Connection: GetProtocol.";
278 d->logUtility->logMessage(strMessage);
279 return protocol_vicar;
282 uint Connection::GetStatus()
284 QString strMessage = "VICaR Connection: GetStatus.";
285 d->logUtility->logMessage(strMessage);
286 return static_cast<uint>(d->connection_status);
289 uint Connection::GetSelfHandle()
291 QString strMessage = "VICaR Connection: GetSelfHandle";
292 d->logUtility->logMessage(strMessage);
293 if (d->connection_status != Connected)
295 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
296 "VICaR - Unable to get Self Handle. The connection is no longer available.");
297 strMessage = "VICaR Connection: NOT CONNECTED when requesting selfhandle!";
298 d->logUtility->logMessage(strMessage);
302 //WARNING: Incomplete implemenation
303 uint handle(SELF_HANDLE);
304 strMessage = "VICaR Connection: Returning Handle " + QString::number(handle) + "as self handle.";
305 d->logUtility->logMessage(strMessage);
309 QList<uint> Connection::RequestHandles(uint handle_type,
310 const QStringList & names)
312 QString strMessage = "VICaR Connection: RequestHandles.";
313 d->logUtility->logMessage(strMessage);
319 if (d->connection_status != Connected)
321 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
322 "VICaR - Unable to process handle request. The connection is no longer available.");
325 if (handle_type != HandleContact)
327 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
328 "VICaR - Supports handles of type Contact only.");
332 //WARNING: Incomplete implementation. Create a handle and return the value here.
333 result.append(this->GetSelfHandle());
337 void Connection::HoldHandles(const uint handle_type, const QList<uint> &handles)
340 QString strMessage = "VICaR Connection: HoldHandles.";
341 d->logUtility->logMessage(strMessage);
342 if (d->connection_status != Connected)
345 strMessage = "VICaR Connection: HoldHandles - Not Connected.";
346 d->logUtility->logMessage(strMessage);
348 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
349 "VICaR - Unable to process handle request. The connection is no longer available.");
352 if (handle_type != HandleContact)
355 strMessage = "VICaR Connection: HoldHandles - Invalid Handle Type.";
356 d->logUtility->logMessage(strMessage);
358 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
359 "VICaR - Supports handles of type Contact only.");
363 //WARNING: Incomplete implementation
366 QStringList Connection::InspectHandles(const uint handle_type,
367 const QList<uint> &handles)
370 QStringList handlesList;
372 QString strMessage = "VICaR Connection: InspectHandles.";
373 //d->logUtility->logMessage(strMessage);
376 if (d->connection_status != Connected)
378 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
379 "VICaR - Unable to process handle request. The connection is no longer available.");
382 if (handle_type != HandleContact)
384 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
385 "VICaR - Supports handles of type Contact only.");
391 qDebug() << "VICaR Connction: " << handles.length()<< " handles passed to us";
392 for (int i = 0 ; i < handles.length(); i++) {
393 handle = handles.at(i);
394 strMessage = "VICaR Connection: Inspecting handle "+QString::number(handle);
395 d->logUtility->logMessage(strMessage);
396 handlesList.append(QString::number(handle));
399 strMessage = "VICaR Connection: Handle inspection completed";
400 d->logUtility->logMessage(strMessage);
402 //WARNING: Incomplete implementation
406 void Connection::ReleaseHandles(const uint handle_type, const QList<uint> &handles)
409 QString strMessage = "VICaR Connection: ReleaseHandles.";
410 d->logUtility->logMessage(strMessage);
412 if (d->connection_status != Connected)
414 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
415 "VICaR - Unable to release handle. The connection is no longer available.");
416 strMessage = "VICaR Connection: Releasing Handle while connection is no longer connected.";
417 d->logUtility->logMessage(strMessage);
420 if (handle_type != HandleContact)
422 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
423 "VICaR - Supports handles of type Contact only.");
424 strMessage = "VICaR Connection: Trying to release a Handle that is not a contact.";
425 d->logUtility->logMessage(strMessage);
429 //WARNING: Incomplete implementation
432 org::freedesktop::Telepathy::ChannelInfoList Connection::ListChannels()
435 QString strMessage = "VICaR Connection: ListChannels.";
436 d->logUtility->logMessage(strMessage);
438 org::freedesktop::Telepathy::ChannelInfoList result;
439 if (d->connection_status != Connected)
441 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
442 "VICaR - Unable to list channels. The connection is no longer available.");
446 //WARNING: Incomplete implementation
447 //Btw - We never have any channels :)
452 QDBusObjectPath Connection::RequestChannel(const QString &type,
453 uint handle_type, uint handle,
454 bool suppress_handler)
457 Q_UNUSED(suppress_handler);
458 //This method is deprecated and no longer used as per latest Telepathy spec
461 QString strMessage = "VICaR Connection: RequestChannel.";
462 d->logUtility->logMessage(strMessage);
465 if (type != QString("org.freedesktop.Telepathy.Channel.Type.StreamedMedia"))
467 sendErrorReply("org.freedesktop.Telepathy.Error.NotImplemented",
468 "VICaR Connection: Failed to create channel: Channel type not implemented.");
469 return QDBusObjectPath();
472 if (handle_type != HandleContact )
474 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidHandle",
475 "VICaR Connection: Failed to create channel: Handle type not supported.");
476 return QDBusObjectPath();
479 if (d->connection_status != Connected)
481 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
482 "VICaR Connection: Failed to create channel: Connection is Disconnected.");
483 return QDBusObjectPath();
486 //WARNING: Incomplete implementation, we are not creating any channels here at all.
487 QDBusObjectPath channel_path;
488 qDebug() << "VICaR Connection: Returning null channel object path";
492 //org.freedesktop.Telepathy.Connection.Interface.Requests
493 QDBusObjectPath Connection::CreateChannel(const QVariantMap &request,
494 QVariantMap &channel_properties)
496 Q_UNUSED(channel_properties);
497 Q_ASSERT(!request.isEmpty());
499 strMessage = "VICaR Connection: CreateChannel";
500 d->logUtility->logMessage(strMessage);
501 qDebug() << " Request details are: "<< request;
503 //Ideally we need to emit NewChannels signal here, but since we are not creating any channels we ignore it
505 //WARNING: VICaR - Specific implementation
506 return processChannel(request);
510 bool Connection::EnsureChannel(const QVariantMap &request,
511 QDBusObjectPath &channel_object,
512 QVariantMap &channel_properties)
514 Q_UNUSED(channel_object);
515 Q_UNUSED(channel_properties);
516 Q_ASSERT(!request.isEmpty());
517 QString strMessage = "VICaR Connection: EnsureChannel";
518 d->logUtility->logMessage(strMessage);
519 qDebug() << " Request details are: "<< request;
521 //WARNING: Incomplete implementation
522 processChannel(request);
527 QDBusObjectPath Connection::processChannel(const QVariantMap &request){
529 QString strMessage = "VICaR Connection: ProcessChannel";
530 d->logUtility->logMessage(strMessage);
532 QDBusObjectPath channel_path;
534 if (!request.contains("org.freedesktop.Telepathy.Channel.TargetID")){
535 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
536 "VICaR - Invalid request. TargetID (Phone Number) not included.");
540 QVariant vNumber = request.value("org.freedesktop.Telepathy.Channel.TargetID");
541 if (!vNumber.isValid()){
542 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
543 "VICaR - Invalid request. Phone Number is not valid.");
546 QString strNumber = vNumber.toString();
547 if (strNumber.isEmpty()){
548 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
549 "VICaR - Invalid request. Phone Number is empty.");
552 else if (strNumber == "publish" || strNumber == "subscribe"){
553 //Deny the persistent Mission control requests to publish and subscribe
554 QString strError = "VICaR - Invalid request. " + strNumber + " is not supported.";
555 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
561 //Only allow requests with handle type as contact
562 QVariant vTargetHandleType = request.value("org.freedesktop.Telepathy.Channel.TargetHandleType");
563 uint intTargetHandleType = vTargetHandleType.toUInt();
564 if (intTargetHandleType != HandleContact)
566 strMessage = "VICaR - Supports handles of type Contact only. Recieved handle type ";
567 strMessage.append(vTargetHandleType.toString());
569 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
576 Send an error reply to Tp Client (Mission Control) to force it to close the active channel.
577 Once it recieves the reply, the client does not bother what we return.
581 sendErrorReply("org.freedesktop.Telepathy.Error.NotAvailable",
582 "VICaR - Creating a new channel to "+strNumber+" via Ring.");
585 //Initiate a new call to CC/Google Out/Skype-out number by requesting a new channel with Ring CM.
587 VicarCallRouterProxy *callRouter = new VicarCallRouterProxy(APPLICATION_DBUS_SERVICE,APPLICATION_DBUS_PATH,QDBusConnection::sessionBus(),this);
589 callRouter->callInternationalNumber(strNumber);
591 strMessage = "VICaR Connection: Call is processed.";
593 d->logUtility->logMessage(strMessage);
599 void Connection::AddClientInterest(const QStringList &tokens){
600 //WARNING: Incomplete implementation
604 strMessage = "VICaR Connection: AddClientInterest";
605 d->logUtility->logMessage(strMessage);
608 void Connection::RemoveClientInterest(const QStringList &tokens){
609 //WARNING: Incomplete implementation
613 strMessage = "VICaR Connection: RemoveClientInterest";
614 d->logUtility->logMessage(strMessage);
617 //org.freedesktop.Telepathy.Connection.Interface.Capabilities
618 org::freedesktop::Telepathy::ContactCapabilitiesList Connection::GetCapabilities(const QList<uint> &Handles){
620 org::freedesktop::Telepathy::ContactCapabilitiesList capabilities;
626 org::freedesktop::Telepathy::CapabilityPairList Connection::AdvertiseCapabilities(org::freedesktop::Telepathy::CapabilityPairList Add, const QStringList &Remove){
629 org::freedesktop::Telepathy::CapabilityPairList capabilities;