Update VoiceCallManager to match latest oFono
[profile/ivi/ofono-qt.git] / lib / ofonovoicecallmanager.cpp
1 /*
2  * This file is part of ofono-qt
3  *
4  * Copyright (C) 2010-2011 Nokia Corporation and/or its subsidiary(-ies).
5  *
6  * Contact: Alexander Kanavin <alex.kanavin@gmail.com>
7  *
8  * Portions of this file are Copyright (C) 2011 Intel Corporation
9  * Contact: Shane Bryan <shane.bryan@linux.intel.com>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * version 2.1 as published by the Free Software Foundation.
14  *
15  * This library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  *
25  */
26
27 #include <QtDBus/QtDBus>
28 #include <QtCore/QObject>
29
30 #include "ofonovoicecallmanager.h"
31 #include "ofonointerface.h"
32
33 #define DIAL_TIMEOUT 30000
34 #define TONE_TIMEOUT 10000
35 #define TRANSFER_TIMEOUT 20000
36 #define SWAP_TIMEOUT 20000
37 #define HANGUP_TIMEOUT 30000
38 #define HOLD_TIMEOUT 30000
39 #define PRIVATE_CHAT_TIMEOUT 30000
40 #define CREATE_MULTIPARTY_TIMEOUT 30000
41
42 QDBusArgument &operator<<(QDBusArgument &argument, const OfonoVoiceCallManagerStruct &call)
43 {
44     argument.beginStructure();
45     argument << call.path << call.properties;
46     argument.endStructure();
47     return argument;
48 }
49
50 const QDBusArgument &operator>>(const QDBusArgument &argument, OfonoVoiceCallManagerStruct &call)
51 {
52     argument.beginStructure();
53     argument >> call.path >> call.properties;
54     argument.endStructure();
55     return argument;
56 }
57
58 OfonoVoiceCallManager::OfonoVoiceCallManager(OfonoModem::SelectionSetting modemSetting, const QString &modemPath, QObject *parent)
59     : OfonoModemInterface(modemSetting, modemPath, "org.ofono.VoiceCallManager", OfonoGetAllOnStartup, parent)
60 {
61     qDBusRegisterMetaType<OfonoVoiceCallManagerStruct>();
62     qDBusRegisterMetaType<OfonoVoiceCallManagerList>();
63
64     m_calllist = getCallList();
65
66     connect(m_if, SIGNAL(propertyChanged(const QString&, const QVariant&)), 
67             this, SLOT(propertyChanged(const QString&, const QVariant&)));
68     connect(this, SIGNAL(validityChanged(bool)),
69             this, SLOT(validityChanged(bool)));
70     connect(modem(), SIGNAL(pathChanged(QString)), this, SLOT(pathChanged(const QString&)));
71
72     connectDbusSignals(path());
73 }
74
75 OfonoVoiceCallManager::~OfonoVoiceCallManager()
76 {
77 }
78
79
80 void OfonoVoiceCallManager::validityChanged(bool /*validity*/)
81 {
82     m_calllist = getCallList();
83 }
84
85 void OfonoVoiceCallManager::pathChanged(const QString& path)
86 {
87     connectDbusSignals(path);
88 }
89
90 QStringList OfonoVoiceCallManager::getCallList()
91 {
92     QDBusReply<OfonoVoiceCallManagerList> reply;
93     OfonoVoiceCallManagerList calls;
94
95     QDBusMessage request;
96     QStringList messageList;
97
98     qDBusRegisterMetaType<OfonoVoiceCallManagerStruct>();
99     qDBusRegisterMetaType<OfonoVoiceCallManagerList>();
100
101     request = QDBusMessage::createMethodCall("org.ofono",
102                                              path(), m_if->ifname(),
103                                              "GetCalls");
104     reply = QDBusConnection::systemBus().call(request);
105
106     calls = reply;
107     foreach(OfonoVoiceCallManagerStruct call, calls) {
108         messageList<< call.path.path();
109     }
110     return messageList;
111 }
112
113 void OfonoVoiceCallManager::connectDbusSignals(const QString& path)
114 {
115     QDBusConnection::systemBus().disconnect("org.ofono", QString(), m_if->ifname(),
116                                          "CallAdded", this,
117                                          SLOT(callAddedChanged(const QDBusObjectPath&, const QVariantMap&)));
118     QDBusConnection::systemBus().disconnect("org.ofono", QString(), m_if->ifname(),
119                                          "CallRemoved", this,
120                                          SLOT(callRemovedChanged(const QDBusObjectPath&)));
121     QDBusConnection::systemBus().disconnect("org.ofono", QString(), m_if->ifname(), 
122                                         "BarringActive", this,
123                                         SIGNAL(barringActive(const QString&)));
124     QDBusConnection::systemBus().disconnect("org.ofono", QString(), m_if->ifname(), 
125                                         "Forwarded", this,
126                                         SIGNAL(forwarded(const QString&)));
127
128     QDBusConnection::systemBus().connect("org.ofono", path, m_if->ifname(),
129                                          "CallAdded", this,
130                                          SLOT(callAddedChanged(const QDBusObjectPath&, const QVariantMap&)));
131     QDBusConnection::systemBus().connect("org.ofono", path, m_if->ifname(),
132                                          "CallRemoved", this,
133                                          SLOT(callRemovedChanged(const QDBusObjectPath&)));
134     QDBusConnection::systemBus().connect("org.ofono", path, m_if->ifname(), 
135                                         "BarringActive", this,
136                                         SIGNAL(barringActive(const QString&)));
137     QDBusConnection::systemBus().connect("org.ofono", path, m_if->ifname(), 
138                                         "Forwarded", this,
139                                         SIGNAL(forwarded(const QString&)));
140 }
141
142 void OfonoVoiceCallManager::dial(const QString &number, const QString &callerid_hide)
143 {
144     QDBusMessage request;
145     request = QDBusMessage::createMethodCall("org.ofono",
146                                              path(), m_if->ifname(),
147                                              "Dial");
148     QList<QVariant>arg;
149     arg.append(QVariant(number));
150     arg.append(QVariant(callerid_hide));
151     request.setArguments(arg);
152     QDBusConnection::systemBus().callWithCallback(request, this,
153                                         SLOT(dialResp()),
154                                         SLOT(dialErr(const QDBusError&)),
155                                         DIAL_TIMEOUT);
156 }
157
158 void OfonoVoiceCallManager::hangupAll()
159 {
160     QDBusMessage request;
161     request = QDBusMessage::createMethodCall("org.ofono",
162                                              path(), m_if->ifname(),
163                                              "HangupAll");
164
165     QDBusConnection::systemBus().callWithCallback(request, this,
166                                         SLOT(hangupAllResp()),
167                                         SLOT(hangupAllErr(const QDBusError&)),
168                                         HANGUP_TIMEOUT);
169 }
170
171 void OfonoVoiceCallManager::sendTones(const QString &tonestring)
172 {
173     QDBusMessage request;
174     request = QDBusMessage::createMethodCall("org.ofono",
175                                              path(), m_if->ifname(),
176                                              "SendTones");
177     QList<QVariant>arg;
178     arg.append(QVariant(tonestring));
179     request.setArguments(arg);
180
181     QDBusConnection::systemBus().callWithCallback(request, this,
182                                         SLOT(sendTonesResp()),
183                                         SLOT(sendTonesErr(const QDBusError&)),
184                                         (TONE_TIMEOUT*tonestring.length()));
185 }
186
187 void OfonoVoiceCallManager::transfer()
188 {
189     QDBusMessage request;
190     request = QDBusMessage::createMethodCall("org.ofono",
191                                              path(), m_if->ifname(),
192                                              "Transfer");
193
194     QDBusConnection::systemBus().callWithCallback(request, this,
195                                         SLOT(transferResp()),
196                                         SLOT(transferErr(const QDBusError&)),
197                                         TRANSFER_TIMEOUT);
198 }
199
200 void OfonoVoiceCallManager::swapCalls()
201 {
202     QDBusMessage request;
203     request = QDBusMessage::createMethodCall("org.ofono",
204                                              path(), m_if->ifname(),
205                                              "SwapCalls");
206
207     QDBusConnection::systemBus().callWithCallback(request, this,
208                                         SLOT(swapCallsResp()),
209                                         SLOT(swapCallsErr(const QDBusError&)),
210                                         SWAP_TIMEOUT);
211 }
212
213 void OfonoVoiceCallManager::releaseAndAnswer()
214 {
215     QDBusMessage request;
216     request = QDBusMessage::createMethodCall("org.ofono",
217                                              path(), m_if->ifname(),
218                                              "ReleaseAndAnswer");
219
220     QDBusConnection::systemBus().callWithCallback(request, this,
221                                         SLOT(releaseAndAnswerResp()),
222                                         SLOT(releaseAndAnswerErr(const QDBusError&)),
223                                         HANGUP_TIMEOUT);
224 }
225
226 void OfonoVoiceCallManager::holdAndAnswer()
227 {
228     QDBusMessage request;
229     request = QDBusMessage::createMethodCall("org.ofono",
230                                              path(), m_if->ifname(),
231                                              "HoldAndAnswer");
232
233     QDBusConnection::systemBus().callWithCallback(request, this,
234                                         SLOT(holdAndAnswerResp()),
235                                         SLOT(holdAndAnswerErr(const QDBusError&)),
236                                         HOLD_TIMEOUT);
237 }
238
239 void OfonoVoiceCallManager::privateChat(const QString &call)
240 {
241     QDBusMessage request;
242     request = QDBusMessage::createMethodCall("org.ofono",
243                                              path(), m_if->ifname(),
244                                              "PrivateChat");
245
246     QList<QVariant>arg;
247     arg.append(qVariantFromValue(QDBusObjectPath(call)));
248     request.setArguments(arg);
249     QDBusConnection::systemBus().callWithCallback(request, this,
250                                         SLOT(privateChatResp(const QList<QDBusObjectPath>&)),
251                                         SLOT(privateChatErr(const QDBusError&)),
252                                         PRIVATE_CHAT_TIMEOUT);
253 }
254
255 void OfonoVoiceCallManager::createMultiparty()
256 {
257     QDBusMessage request;
258     request = QDBusMessage::createMethodCall("org.ofono",
259                                              path(), m_if->ifname(),
260                                              "CreateMultiparty");
261
262     QDBusConnection::systemBus().callWithCallback(request, this,
263                                         SLOT(createMultipartyResp(const QList<QDBusObjectPath>&)),
264                                         SLOT(createMultipartyErr(const QDBusError&)),
265                                         CREATE_MULTIPARTY_TIMEOUT);
266 }
267
268 void OfonoVoiceCallManager::hangupMultiparty()
269 {
270     QDBusMessage request;
271     request = QDBusMessage::createMethodCall("org.ofono",
272                                              path(), m_if->ifname(),
273                                              "HangupMultiparty");
274
275     QDBusConnection::systemBus().callWithCallback(request, this,
276                                         SLOT(hangupMultipartyResp()),
277                                         SLOT(hangupMultipartyErr(const QDBusError&)),
278                                         HANGUP_TIMEOUT);
279 }
280
281 void OfonoVoiceCallManager::hangupMultipartyResp()
282 {
283     emit hangupMultipartyComplete(TRUE);
284 }
285
286 void OfonoVoiceCallManager::hangupMultipartyErr(const QDBusError &error)
287 {
288     m_if->setError(error.name(), error.message());
289     emit hangupMultipartyComplete(FALSE);
290 }
291
292 void OfonoVoiceCallManager::createMultipartyResp(const QList<QDBusObjectPath> &paths)
293 {
294     QStringList calls;
295     foreach(QDBusObjectPath path, paths)
296         calls << path.path();
297     emit createMultipartyComplete(TRUE, calls);
298 }
299
300 void OfonoVoiceCallManager::createMultipartyErr(const QDBusError &error)
301 {
302     m_if->setError(error.name(), error.message());
303     emit createMultipartyComplete(FALSE, QStringList());
304 }
305
306 void OfonoVoiceCallManager::privateChatResp(const QList<QDBusObjectPath> &paths)
307 {
308     QStringList calls;
309     foreach(QDBusObjectPath path, paths)
310         calls << path.path();
311     emit privateChatComplete(TRUE, calls);
312 }
313
314 void OfonoVoiceCallManager::privateChatErr(const QDBusError &error)
315 {
316     m_if->setError(error.name(), error.message());
317     emit privateChatComplete(FALSE, QStringList());
318 }
319
320 void OfonoVoiceCallManager::holdAndAnswerResp()
321 {
322     emit holdAndAnswerComplete(TRUE);
323 }
324
325 void OfonoVoiceCallManager::holdAndAnswerErr(const QDBusError &error)
326 {
327     m_if->setError(error.name(), error.message());
328     emit holdAndAnswerComplete(FALSE);
329 }
330
331 void OfonoVoiceCallManager::releaseAndAnswerResp()
332 {
333     emit releaseAndAnswerComplete(TRUE);
334 }
335
336 void OfonoVoiceCallManager::releaseAndAnswerErr(const QDBusError &error)
337 {
338     m_if->setError(error.name(), error.message());
339     emit releaseAndAnswerComplete(FALSE);
340 }
341
342 void OfonoVoiceCallManager::swapCallsResp()
343 {
344     emit swapCallsComplete(TRUE);
345 }
346
347 void OfonoVoiceCallManager::swapCallsErr(const QDBusError &error)
348 {
349     m_if->setError(error.name(), error.message());
350     emit swapCallsComplete(FALSE);
351 }
352
353 void OfonoVoiceCallManager::dialResp()
354 {
355     emit dialComplete(TRUE);
356 }
357
358 void OfonoVoiceCallManager::dialErr(const QDBusError &error)
359 {
360     m_if->setError(error.name(), error.message());
361     emit dialComplete(FALSE);
362 }
363
364 void OfonoVoiceCallManager::hangupAllResp()
365 {
366     emit hangupAllComplete(TRUE);
367 }
368
369 void OfonoVoiceCallManager::hangupAllErr(const QDBusError &error)
370 {
371     m_if->setError(error.name(), error.message());
372     emit hangupAllComplete(FALSE);
373 }
374 void OfonoVoiceCallManager::sendTonesResp()
375 {
376     emit sendTonesComplete(TRUE);
377 }
378
379 void OfonoVoiceCallManager::sendTonesErr(const QDBusError &error)
380 {
381     m_if->setError(error.name(), error.message());
382     emit sendTonesComplete(FALSE);
383 }
384
385 void OfonoVoiceCallManager::transferResp()
386 {
387     emit transferComplete(TRUE);
388 }
389
390 void OfonoVoiceCallManager::transferErr(const QDBusError &error)
391 {
392     m_if->setError(error.name(), error.message());
393     emit transferComplete(FALSE);
394 }
395
396 QStringList OfonoVoiceCallManager::emergencyNumbers() const
397 {
398     return m_if->properties()["EmergencyNumbers"].value<QStringList>();
399 }
400
401 void OfonoVoiceCallManager::propertyChanged(const QString &property, const QVariant &value)
402 {
403     if (property == "EmergencyNumbers") {       
404         emit emergencyNumbersChanged(value.value<QStringList>());
405     }
406 }
407
408 QStringList OfonoVoiceCallManager::getCalls() const
409 {
410     return m_calllist;
411 }
412
413 void OfonoVoiceCallManager::callAddedChanged(const QDBusObjectPath &path, const QVariantMap& /*values*/)
414 {
415     m_calllist << path.path();
416     emit callAdded(path.path());
417 }
418
419 void OfonoVoiceCallManager::callRemovedChanged(const QDBusObjectPath &path)
420 {
421     m_calllist.removeAll(path.path());
422     emit callRemoved(path.path());
423 }