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);
122 //this->setProperty("SelfHandle",org::freedesktop::Telepathy::HANDLE_TYPE_CONTACT);
123 uint selfHandle(SELF_HANDLE);
124 this->setProperty("SelfHandle",selfHandle);
126 strMessage = "VICaR Connection: Emitting SelfHandleChanged.";
127 d->logUtility->logMessage(strMessage);
128 emit SelfHandleChanged(selfHandle);
130 //Set the property RequestableChannelClasses
131 org::freedesktop::Telepathy::RequestableChannelClassList requestableChannelClasses;
133 uint targetHandleType(1);
135 org::freedesktop::Telepathy::RequestableChannelClass requestableChannelClass1;
136 requestableChannelClass1.fixedProperties.insert("org.freedesktop.Telepathy.Channel.TargetHandleType",targetHandleType);
137 requestableChannelClass1.fixedProperties.insert("org.freedesktop.Telepathy.Channel.ChannelType","org.freedesktop.Telepathy.Channel.Type.StreamedMedia");
139 requestableChannelClass1.allowedProperties.append("org.freedesktop.Telepathy.Channel.TargetHandle");
140 requestableChannelClass1.allowedProperties.append("org.freedesktop.Telepathy.Channel.Type.StreamedMedia.InitialAudio");
142 requestableChannelClasses.append(requestableChannelClass1);
144 org::freedesktop::Telepathy::RequestableChannelClass requestableChannelClass2;
145 requestableChannelClass2.fixedProperties.insert("org.freedesktop.Telepathy.Channel.TargetHandleType",targetHandleType);
146 requestableChannelClass2.fixedProperties.insert("org.freedesktop.Telepathy.Channel.ChannelType","org.freedesktop.Telepathy.Channel.Type.StreamedMedia");
148 requestableChannelClass2.allowedProperties.append("com.nokia.Telepathy.Channel.Interface.Conference.InitialMembers");
149 requestableChannelClass2.allowedProperties.append("org.freedesktop.Telepathy.Channel.TargetHandleType");
150 requestableChannelClass2.allowedProperties.append("org.freedesktop.Telepathy.Channel.Type.StreamedMedia.InitialAudio");
152 requestableChannelClasses.append(requestableChannelClass2);
155 this->setProperty("RequestableChannelClasses",QVariant::fromValue(requestableChannelClasses));
157 //Set the property Channels
158 org::freedesktop::Telepathy::ChannelDetailsList channelDetails;
159 this->setProperty("Channels",QVariant::fromValue(channelDetails));
161 //Set the connection status to Connected (default for Vicar)
162 d->connection_status = Connection::Connected;
165 strMessage = "VICaR Connection: Connection set up.";
166 d->logUtility->logMessage(strMessage);
169 Connection::~Connection()
171 qDebug() << "VICaR Connection: Connection closed.";
175 bool Connection::registerObject()
179 if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName())){
180 if (!QDBusConnection::sessionBus().registerService(serviceName()))
182 strMessage = "VICaR Connection: Problem registering connection service:" + serviceName();
183 d->logUtility->logMessage(strMessage);
187 if (!QDBusConnection::sessionBus().registerObject(objectPath().path(),
190 strMessage = "VICaR Connection: Problem registering object path:" + objectPath().path();
191 d->logUtility->logMessage(strMessage);
196 strMessage = "VICaR Connection: " + serviceName()+" is already registered on DBus";
197 d->logUtility->logMessage(strMessage);
202 void Connection::unregisterObject()
204 QString strMessage = "VICaR Connection: Unregistering Connection object from DBus";
205 d->logUtility->logMessage(strMessage);
206 QDBusConnection::sessionBus().unregisterObject(objectPath().path());
207 QDBusConnection::sessionBus().unregisterService(serviceName());
210 QString Connection::name() const
212 return QString("vicar");
216 QString Connection::serviceName() const
217 { return connection_service_name_prefix + name(); }
219 QDBusObjectPath Connection::objectPath() const
220 { return QDBusObjectPath(connection_object_path_prefix + name()); }
223 //org.freedesktop.Telepathy.Connection
224 void Connection::Connect()
227 Since this is not a "real" Telepathy Connection to a SIP, Chat server,
228 I am not connecting to anything.
230 QString strMessage = "VICaR Connection: Changing status to Connected...";
231 d->logUtility->logMessage(strMessage);
232 d->connection_status = Connection::Connected;
234 //Let all the Telepathy clients know that connection status has changed
235 strMessage = "VICaR Connection: Emitting StatusChanged.";
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 d->logUtility->logMessage(strMessage);
244 //We don't have any Handles to release here. So just change the status to Disconnected
245 d->connection_status = Connection::Disconnected;
247 strMessage = "VICaR Connection: Emitting StatusChanged";
248 d->logUtility->logMessage(strMessage);
249 emit StatusChanged(d->connection_status, ReasonRequested);
251 //As per Telepathy specfication, on disconnect we need to unregister from Dbus and destroy the object.
256 QStringList Connection::GetInterfaces()
260 QString strMessage = "VICaR Connection: GetInterfaces.";
261 d->logUtility->logMessage(strMessage);
263 if (d->connection_status != Connected)
265 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
266 "VICaR - Unable to get Interfaces List. The connection is no longer available.");
269 result <<requests_interface;
273 QString Connection::GetProtocol()
275 QString strMessage = "VICaR Connection: GetProtocol.";
276 d->logUtility->logMessage(strMessage);
277 return protocol_vicar;
280 uint Connection::GetStatus()
282 QString strMessage = "VICaR Connection: GetStatus.";
283 d->logUtility->logMessage(strMessage);
284 return static_cast<uint>(d->connection_status);
287 uint Connection::GetSelfHandle()
289 QString strMessage = "VICaR Connection: GetSelfHandle";
290 d->logUtility->logMessage(strMessage);
291 if (d->connection_status != Connected)
293 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
294 "VICaR - Unable to get Self Handle. The connection is no longer available.");
295 strMessage = "VICaR Connection: NOT CONNECTED when requesting selfhandle!";
296 d->logUtility->logMessage(strMessage);
300 //WARNING: Incomplete implemenation
301 uint handle(SELF_HANDLE);
302 strMessage = "VICaR Connection: Returning Handle " + QString::number(handle) + "as self handle.";
303 d->logUtility->logMessage(strMessage);
307 QList<uint> Connection::RequestHandles(uint handle_type,
308 const QStringList & names)
310 QString strMessage = "VICaR Connection: RequestHandles.";
311 d->logUtility->logMessage(strMessage);
317 if (d->connection_status != Connected)
319 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
320 "VICaR - Unable to process handle request. The connection is no longer available.");
323 if (handle_type != HandleContact)
325 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
326 "VICaR - Supports handles of type Contact only.");
330 //WARNING: Incomplete implementation. Create a handle and return the value here.
331 result.append(this->GetSelfHandle());
335 void Connection::HoldHandles(const uint handle_type, const QList<uint> &handles)
338 QString strMessage = "VICaR Connection: HoldHandles.";
339 d->logUtility->logMessage(strMessage);
340 if (d->connection_status != Connected)
343 strMessage = "VICaR Connection: HoldHandles - Not Connected.";
344 d->logUtility->logMessage(strMessage);
346 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
347 "VICaR - Unable to process handle request. The connection is no longer available.");
350 if (handle_type != HandleContact)
353 strMessage = "VICaR Connection: HoldHandles - Invalid Handle Type.";
354 d->logUtility->logMessage(strMessage);
356 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
357 "VICaR - Supports handles of type Contact only.");
361 //WARNING: Incomplete implementation
364 QStringList Connection::InspectHandles(const uint handle_type,
365 const QList<uint> &handles)
368 QStringList handlesList;
370 QString strMessage = "VICaR Connection: InspectHandles.";
371 d->logUtility->logMessage(strMessage);
374 if (d->connection_status != Connected)
376 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
377 "VICaR - Unable to process handle request. The connection is no longer available.");
380 if (handle_type != HandleContact)
382 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
383 "VICaR - Supports handles of type Contact only.");
389 qDebug() << "VICaR Connction: " << handles.length()<< " handles passed to us";
390 for (int i = 0 ; i < handles.length(); i++) {
391 handle = handles.at(i);
392 strMessage = "VICaR Connection: Inspecting handle "+QString::number(handle);
393 d->logUtility->logMessage(strMessage);
394 handlesList.append(QString::number(handle));
397 strMessage = "VICaR Connection: Handle inspection completed";
398 d->logUtility->logMessage(strMessage);
400 //WARNING: Incomplete implementation
404 void Connection::ReleaseHandles(const uint handle_type, const QList<uint> &handles)
407 QString strMessage = "VICaR Connection: ReleaseHandles.";
408 d->logUtility->logMessage(strMessage);
410 if (d->connection_status != Connected)
412 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
413 "VICaR - Unable to release handle. The connection is no longer available.");
414 strMessage = "VICaR Connection: Releasing Handle while connection is no longer connected.";
415 d->logUtility->logMessage(strMessage);
418 if (handle_type != HandleContact)
420 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
421 "VICaR - Supports handles of type Contact only.");
422 strMessage = "VICaR Connection: Trying to release a Handle that is not a contact.";
423 d->logUtility->logMessage(strMessage);
427 //WARNING: Incomplete implementation
430 org::freedesktop::Telepathy::ChannelInfoList Connection::ListChannels()
433 QString strMessage = "VICaR Connection: ListChannels.";
434 d->logUtility->logMessage(strMessage);
436 org::freedesktop::Telepathy::ChannelInfoList result;
437 if (d->connection_status != Connected)
439 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
440 "VICaR - Unable to list channels. The connection is no longer available.");
444 //WARNING: Incomplete implementation
445 //Btw - We never have any channels :)
450 QDBusObjectPath Connection::RequestChannel(const QString &type,
451 uint handle_type, uint handle,
452 bool suppress_handler)
455 Q_UNUSED(suppress_handler);
456 //This method is deprecated and no longer used as per latest Telepathy spec
459 QString strMessage = "VICaR Connection: RequestChannel.";
460 d->logUtility->logMessage(strMessage);
463 if (type != QString("org.freedesktop.Telepathy.Channel.Type.StreamedMedia"))
465 sendErrorReply("org.freedesktop.Telepathy.Error.NotImplemented",
466 "VICaR Connection: Failed to create channel: Channel type not implemented.");
467 return QDBusObjectPath();
470 if (handle_type != HandleContact )
472 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidHandle",
473 "VICaR Connection: Failed to create channel: Handle type not supported.");
474 return QDBusObjectPath();
477 if (d->connection_status != Connected)
479 sendErrorReply("org.freedesktop.Telepathy.Error.Disconnected",
480 "VICaR Connection: Failed to create channel: Connection is Disconnected.");
481 return QDBusObjectPath();
484 //WARNING: Incomplete implementation, we are not creating any channels here at all.
485 QDBusObjectPath channel_path;
486 qDebug() << "VICaR Connection: Returning null channel object path";
490 //org.freedesktop.Telepathy.Connection.Interface.Requests
491 QDBusObjectPath Connection::CreateChannel(const QVariantMap &request,
492 QVariantMap &channel_properties)
494 Q_UNUSED(channel_properties);
495 Q_ASSERT(!request.isEmpty());
497 strMessage = "VICaR Connection: CreateChannel";
498 d->logUtility->logMessage(strMessage);
499 qDebug() << " Request details are: "<< request;
501 //Ideally we need to emit NewChannels signal here, but since we are not creating any channels we ignore it
503 //WARNING: VICaR - Specific implementation
504 return processChannel(request);
508 bool Connection::EnsureChannel(const QVariantMap &request,
509 QDBusObjectPath &channel_object,
510 QVariantMap &channel_properties)
512 Q_UNUSED(channel_object);
513 Q_UNUSED(channel_properties);
514 Q_ASSERT(!request.isEmpty());
515 QString strMessage = "VICaR Connection: EnsureChannel";
516 d->logUtility->logMessage(strMessage);
517 qDebug() << " Request details are: "<< request;
519 //WARNING: Incomplete implementation
520 processChannel(request);
525 QDBusObjectPath Connection::processChannel(const QVariantMap &request){
527 QString strMessage = "VICaR Connection: ProcessChannel";
528 d->logUtility->logMessage(strMessage);
530 QDBusObjectPath channel_path;
532 if (!request.contains("org.freedesktop.Telepathy.Channel.TargetID")){
533 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
534 "VICaR - Invalid request. TargetID (Phone Number) not included.");
538 QVariant vNumber = request.value("org.freedesktop.Telepathy.Channel.TargetID");
539 if (!vNumber.isValid()){
540 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
541 "VICaR - Invalid request. Phone Number is not valid.");
544 QString strNumber = vNumber.toString();
545 if (strNumber.isEmpty()){
546 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
547 "VICaR - Invalid request. Phone Number is empty.");
550 else if (strNumber == "publish" || strNumber == "subscribe"){
551 //Deny the persistent Mission control requests to publish and subscribe
552 QString strError = "VICaR - Invalid request. " + strNumber + " is not supported.";
553 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
559 //Only allow requests with handle type as contact
560 QVariant vTargetHandleType = request.value("org.freedesktop.Telepathy.Channel.TargetHandleType");
561 uint intTargetHandleType = vTargetHandleType.toUInt();
562 if (intTargetHandleType != HandleContact)
564 strMessage = "VICaR - Supports handles of type Contact only. Recieved handle type ";
565 strMessage.append(vTargetHandleType.toString());
567 sendErrorReply("org.freedesktop.Telepathy.Error.InvalidArgument",
574 Send an error reply to Tp Client (Mission Control) to force it to close the active channel.
575 Once it recieves the reply, the client does not bother what we return.
579 sendErrorReply("org.freedesktop.Telepathy.Error.NotAvailable",
580 "VICaR - Creating a new channel to "+strNumber+" via Ring.");
583 //Initiate a new call to CC/Google Out/Skype-out number by requesting a new channel with Ring CM.
585 VicarCallRouterProxy *callRouter = new VicarCallRouterProxy(APPLICATION_DBUS_SERVICE,APPLICATION_DBUS_PATH,QDBusConnection::sessionBus(),this);
587 callRouter->callInternationalNumber(strNumber);
589 strMessage = "VICaR Connection: Call is processed.";
591 d->logUtility->logMessage(strMessage);
597 void Connection::AddClientInterest(const QStringList &tokens){
598 //WARNING: Incomplete implementation
602 strMessage = "VICaR Connection: AddClientInterest";
603 d->logUtility->logMessage(strMessage);
606 void Connection::RemoveClientInterest(const QStringList &tokens){
607 //WARNING: Incomplete implementation
611 strMessage = "VICaR Connection: RemoveClientInterest";
612 d->logUtility->logMessage(strMessage);
615 //org.freedesktop.Telepathy.Connection.Interface.Capabilities
616 org::freedesktop::Telepathy::ContactCapabilitiesList Connection::GetCapabilities(const QList<uint> &Handles){
618 org::freedesktop::Telepathy::ContactCapabilitiesList capabilities;
624 org::freedesktop::Telepathy::CapabilityPairList Connection::AdvertiseCapabilities(org::freedesktop::Telepathy::CapabilityPairList Add, const QStringList &Remove){
627 org::freedesktop::Telepathy::CapabilityPairList capabilities;