blob: c58193f905c976019d7efcf4ce9ddce2ea3852da [file] [log] [blame]
Nicolas Jager6e30ad82016-08-26 13:00:27 -04001/**************************************************************************
atraczykb724d332016-08-30 15:25:59 -04002* Copyright (C) 2016 by Savoir-faire Linux *
3* Author: Jäger Nicolas <nicolas.jager@savoirfairelinux.com> *
4* Author: Traczyk Andreas <traczyk.andreas@savoirfairelinux.com> *
5* *
6* This program is free software; you can redistribute it and/or modify *
7* it under the terms of the GNU General Public License as published by *
8* the Free Software Foundation; either version 3 of the License, or *
9* (at your option) any later version. *
10* *
11* This program is distributed in the hope that it will be useful, *
12* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14* GNU General Public License for more details. *
15* *
16* You should have received a copy of the GNU General Public License *
17* along with this program. If not, see <http://www.gnu.org/licenses/>. *
18**************************************************************************/
19#include "pch.h"
20
21/* daemon */
22#include <dring.h>
23#include "callmanager_interface.h"
24#include "configurationmanager_interface.h"
25#include "presencemanager_interface.h"
26#include "fileutils.h"
27
28#include "account_schema.h"
29
30#include "SmartPanel.xaml.h"
31
32using namespace Windows::ApplicationModel::Core;
33using namespace Windows::Storage;
34using namespace Windows::UI::Core;
35
36using namespace RingClientUWP;
37using namespace RingClientUWP::Utils;
Nicolas Jager655df542016-08-31 10:24:47 -040038using namespace RingClientUWP::ViewModel;
atraczykb724d332016-08-30 15:25:59 -040039
40void
41debugOutputWrapper(const std::string& str)
42{
43 MSG_(str);
44}
45
46void
47RingClientUWP::RingD::reloadAccountList()
48{
49 RingClientUWP::ViewModel::AccountsViewModel::instance->clearAccountList();
50 std::vector<std::string> accountList = DRing::getAccountList();
51 std::vector<std::string>::reverse_iterator rit = accountList.rbegin();
52 for (; rit != accountList.rend(); ++rit) {
53 std::map<std::string,std::string> accountDetails = DRing::getAccountDetails(*rit);
54 std::string ringID(accountDetails.find(ring::Conf::CONFIG_ACCOUNT_USERNAME)->second);
55 if(!ringID.empty())
56 ringID = ringID.substr(5);
57 RingClientUWP::ViewModel::AccountsViewModel::instance->add(
58 accountDetails.find(ring::Conf::CONFIG_ACCOUNT_ALIAS)->second, //name
59 ringID, //ringid
atraczyk797fa1a2016-08-31 09:55:53 -040060 accountDetails.find(ring::Conf::CONFIG_ACCOUNT_TYPE)->second, //type
61 *rit);
atraczykb724d332016-08-30 15:25:59 -040062 }
63 // load user preferences
64 Configuration::UserPreferences::instance->load();
65}
66
Nicolas Jager655df542016-08-31 10:24:47 -040067/* nb: send message during conversation not chat video message */
68void RingClientUWP::RingD::sendAccountTextMessage(String^ message)
69{
70 /* account id */
71 auto accountId = AccountsViewModel::instance->selectedAccount->accountID_;
72 std::wstring accountId2(accountId->Begin());
73 std::string accountId3(accountId2.begin(), accountId2.end());
74
75 /* recipient */
76 auto contact = ContactsViewModel::instance->selectedContact;
77 auto toRingId = contact->ringID_;
78 std::wstring toRingId2(toRingId->Begin());
79 std::string toRingId3(toRingId2.begin(), toRingId2.end());
80
81 /* payload(s) */
82 std::wstring message2(message->Begin());
83 std::string message3(message2.begin(), message2.end());
84 std::map<std::string, std::string> payloads;
85 payloads["text/plain"] = message3;
86
87 /* daemon */
88 auto sent = DRing::sendAccountTextMessage(accountId3, toRingId3, payloads);
89
90 /* conversation */
91 if (sent) {
92 contact->_conversation->addMessage(""/* date not yet used*/, MSG_FROM_ME, message);
atraczykf5be5462016-08-31 14:23:06 -040093
94 /* save contacts conversation to disk */
95 contact->saveConversationToFile();
96
Nicolas Jager655df542016-08-31 10:24:47 -040097 } else {
98 WNG_("message not sent, see daemon outputs");
99 }
100}
101
atraczykb724d332016-08-30 15:25:59 -0400102void
103RingClientUWP::RingD::startDaemon()
104{
Nicolas Jagerd76940f2016-08-31 14:44:04 -0400105 // TODO (during refactoring) : use namespace
106 /* clear the calls list and instantiate the singleton (required) */
107 RingClientUWP::ViewModel::CallsViewModel::instance->clearCallsList();
108
atraczykb724d332016-08-30 15:25:59 -0400109 create_task([&]()
110 {
111 using SharedCallback = std::shared_ptr<DRing::CallbackWrapperBase>;
112 using namespace std::placeholders;
113
114 std::map<std::string, SharedCallback> callHandlers = {
115 // use IncomingCall only to register the call client sided, use StateChange to determine the impact on the UI
116 DRing::exportable_callback<DRing::CallSignal::IncomingCall>([this](
117 const std::string& accountId,
118 const std::string& callId,
119 const std::string& from)
120 {
121 MSG_("<IncomingCall>");
122 MSG_("accountId = " + accountId);
123 MSG_("callId = " + callId);
124 MSG_("from = " + from);
125
126 auto accountId2 = toPlatformString(accountId);
127 auto callId2 = toPlatformString(callId);
128 auto from2 = toPlatformString(from);
129
Nicolas Jagerd76940f2016-08-31 14:44:04 -0400130 CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
131 CoreDispatcherPriority::Normal, ref new DispatchedHandler([=]()
132 {
133 incomingCall(accountId2, callId2, from2);
134 stateChange(callId2, "incoming call", 0);
135 }));
atraczykb724d332016-08-30 15:25:59 -0400136 }),
137 DRing::exportable_callback<DRing::CallSignal::StateChange>([this](
Nicolas Jagerd76940f2016-08-31 14:44:04 -0400138 const std::string& callId,
139 const std::string& state,
140 int code)
atraczykb724d332016-08-30 15:25:59 -0400141 {
142 MSG_("<StateChange>");
143 MSG_("callId = " + callId);
144 MSG_("state = " + state);
145 MSG_("code = " + std::to_string(code));
146
147 auto callId2 = toPlatformString(callId);
148 auto state2 = toPlatformString(state);
149
atraczykb724d332016-08-30 15:25:59 -0400150
Nicolas Jagerd76940f2016-08-31 14:44:04 -0400151 CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
152 CoreDispatcherPriority::Low, ref new DispatchedHandler([=]()
153 {
154 stateChange(callId2, state2, code);
155 }));
atraczykb724d332016-08-30 15:25:59 -0400156 }),
Nicolas Jager6e30ad82016-08-26 13:00:27 -0400157 DRing::exportable_callback<DRing::ConfigurationSignal::IncomingAccountMessage>([&](
Nicolas Jagerd76940f2016-08-31 14:44:04 -0400158 const std::string& accountId,
159 const std::string& from,
160 const std::map<std::string, std::string>& payloads)
atraczykb724d332016-08-30 15:25:59 -0400161 {
162 MSG_("<IncomingAccountMessage>");
163 MSG_("accountId = " + accountId);
164 MSG_("from = " + from);
165
Nicolas Jager6e30ad82016-08-26 13:00:27 -0400166 auto accountId2 = toPlatformString(accountId);
167 auto from2 = toPlatformString(from);
168
atraczykb724d332016-08-30 15:25:59 -0400169 for (auto i : payloads) {
170 MSG_("payload = " + i.second);
171 auto payload = Utils::toPlatformString(i.second);
Nicolas Jager6e30ad82016-08-26 13:00:27 -0400172 CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
173 CoreDispatcherPriority::Low, ref new DispatchedHandler([=]()
174 {
175 incomingAccountMessage(accountId2, from2, payload);
176 }));
atraczykb724d332016-08-30 15:25:59 -0400177 }
178 }),
179 DRing::exportable_callback<DRing::ConfigurationSignal::AccountsChanged>([this]()
180 {
181 CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::Normal,
Nicolas Jager655df542016-08-31 10:24:47 -0400182 ref new DispatchedHandler([=]() {
atraczykb724d332016-08-30 15:25:59 -0400183 reloadAccountList();
184 }));
185 })
186 };
187
188 registerCallHandlers(callHandlers);
189
190 std::map<std::string, SharedCallback> dringDebugOutHandler;
191 dringDebugOutHandler.insert(DRing::exportable_callback<DRing::Debug::MessageSend>
192 (std::bind(&debugOutputWrapper, _1)));
193 registerCallHandlers(dringDebugOutHandler);
194
195 std::map<std::string, SharedCallback> getAppPathHandler =
196 {
197 DRing::exportable_callback<DRing::ConfigurationSignal::GetAppDataPath>
198 ([this](std::vector<std::string>* paths) {
199 paths->emplace_back(localFolder_);
200 })
201 };
202 registerCallHandlers(getAppPathHandler);
203
Nicolas Jagerd76940f2016-08-31 14:44:04 -0400204 DRing::init(static_cast<DRing::InitFlag>(/*DRing::DRING_FLAG_CONSOLE_LOG |
205 DRing::DRING_FLAG_DEBUG |*/
206 !DRing::DRING_FLAG_AUTOANSWER));
atraczykb724d332016-08-30 15:25:59 -0400207
208 if (!DRing::start()) {
209 ERR_("\ndaemon didn't start.\n");
210 return;
211 }
212 else {
213 if (!hasConfig)
214 {
atraczyk4464ace2016-09-01 09:37:37 -0400215 tasksList_.push(ref new RingD::Task(Request::AddRingAccount));
216 tasksList_.push(ref new RingD::Task(Request::AddSIPAccount));
atraczykb724d332016-08-30 15:25:59 -0400217 }
218 else {
219 CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::Normal,
Nicolas Jager655df542016-08-31 10:24:47 -0400220 ref new DispatchedHandler([=]() {
atraczykb724d332016-08-30 15:25:59 -0400221 reloadAccountList();
222 }));
223 }
224 while (true) {
225 DRing::pollEvents();
226 Sleep(1000);
227 dequeueTasks();
228 }
229 DRing::fini();
230 }
231 });
232}
233
234RingD::RingD()
235{
236 localFolder_ = Utils::toString(ApplicationData::Current->LocalFolder->Path);
237}
238
239void
240RingD::dequeueTasks()
241{
242 for (int i = 0; i < tasksList_.size(); i++) {
243 auto task = tasksList_.front();
244 switch (task->request) {
245 case Request::None:
atraczyk4464ace2016-09-01 09:37:37 -0400246 break;
247 case Request::AddRingAccount:
Nicolas Jagerd76940f2016-08-31 14:44:04 -0400248 {
249 std::map<std::string, std::string> ringAccountDetails;
250 ringAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_ALIAS, accountName));
251 ringAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_TYPE,"RING"));
252 DRing::addAccount(ringAccountDetails);
253 }
254 break;
atraczyk4464ace2016-09-01 09:37:37 -0400255 case Request::AddSIPAccount:
Nicolas Jagerd76940f2016-08-31 14:44:04 -0400256 {
257 std::map<std::string, std::string> sipAccountDetails;
258 sipAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_ALIAS, accountName + " (SIP)"));
259 sipAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_TYPE,"SIP"));
260 DRing::addAccount(sipAccountDetails);
261 }
262 break;
atraczykb724d332016-08-30 15:25:59 -0400263 default:
264 break;
265 }
266 tasksList_.pop();
267 }
268}