~noskcaj/ubuntu/saucy/sflphone/merge-1.2.3-2

« back to all changes in this revision

Viewing changes to daemon/src/managerimpl.cpp

  • Committer: Package Import Robot
  • Author(s): Francois Marier
  • Date: 2012-02-18 21:47:09 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120218214709-6362d71gqdsdkrj5
Tags: 1.0.2-1
* New upstream release
  - remove logging patch (applied upstream)
  - update s390 patch since it was partially applied upstream
* Include the Evolution plugin as a separate binary package

* Fix compilation issues on SH4 (closes: #658987)
* Merge Ubuntu's binutils-gold linking fix

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
#include "audio/sound/tonelist.h"
50
50
#include "audio/sound/audiofile.h"
51
51
#include "audio/sound/dtmf.h"
52
 
#include "history/historymanager.h"
 
52
#include "history/history.h"
53
53
#include "sip/sipvoiplink.h"
54
54
#include "iax/iaxvoiplink.h"
55
55
#include "manager.h"
62
62
#include <ctime>
63
63
#include <cstdlib>
64
64
#include <iostream>
 
65
#include <iterator>
65
66
#include <fstream>
66
67
#include <sstream>
67
68
#include <sys/types.h> // mkdir(2)
73
74
    hasTriedToRegister_(false), audioCodecFactory(), dbus_(), config_(), currentCallId_(),
74
75
    currentCallMutex_(), audiodriver_(0), dtmfKey_(0), toneMutex_(),
75
76
    telephoneTone_(0), audiofile_(0), speakerVolume_(0), micVolume_(0),
76
 
    audiolayerMutex_(), waitingCall_(), waitingCallMutex_(),
 
77
    audioLayerMutex_(), waitingCall_(), waitingCallMutex_(),
77
78
    nbIncomingWaitingCall_(0), path_(), callAccountMap_(),
78
 
    callAccountMapMutex_(), callConfigMap_(), accountMap_(),
79
 
    mainBuffer_(), conferenceMap_(), history_(new HistoryManager),
 
79
    callAccountMapMutex_(), IPToIPMap_(), accountMap_(),
 
80
    mainBuffer_(), conferenceMap_(), history_(new History),
80
81
    imModule_(new sfl::InstantMessaging)
81
82
{
82
83
    // initialize random generator for call id
120
121
    initVolume();
121
122
    initAudioDriver();
122
123
 
123
 
    audioLayerMutexLock();
124
 
 
125
 
    if (audiodriver_) {
126
 
        telephoneTone_ = new TelephoneTone(preferences.getZoneToneChoice(), audiodriver_->getSampleRate());
127
 
        dtmfKey_ = new DTMF(8000);
 
124
    {
 
125
        ost::MutexLock lock(audioLayerMutex_);
 
126
        if (audiodriver_) {
 
127
            telephoneTone_ = new TelephoneTone(preferences.getZoneToneChoice(), audiodriver_->getSampleRate());
 
128
            dtmfKey_ = new DTMF(8000);
 
129
        }
128
130
    }
129
131
 
130
 
    audioLayerMutexUnlock();
131
 
 
132
 
    history_->load_history(preferences.getHistoryLimit());
 
132
    history_->load(preferences.getHistoryLimit());
133
133
    registerAccounts();
134
134
}
135
135
 
148
148
    delete telephoneTone_;
149
149
    telephoneTone_ = NULL;
150
150
 
151
 
    audioLayerMutexLock();
 
151
    ost::MutexLock lock(audioLayerMutex_);
152
152
 
153
153
    delete audiodriver_;
154
154
    audiodriver_ = NULL;
155
 
 
156
 
    audioLayerMutexUnlock();
157
155
}
158
156
 
159
157
bool ManagerImpl::isCurrentCall(const std::string& callId) const
215
213
    static const char * const SIP_SCHEME = "sip:";
216
214
    static const char * const SIPS_SCHEME = "sips:";
217
215
 
218
 
    Call::CallConfiguration callConfig = (to_cleaned.find(SIP_SCHEME) == 0 or to_cleaned.find(SIPS_SCHEME) == 0) ? Call::IPtoIP : Call::Classic;
 
216
    bool IPToIP = to_cleaned.find(SIP_SCHEME) == 0 or
 
217
                  to_cleaned.find(SIPS_SCHEME) == 0;
219
218
 
220
 
    associateConfigToCall(call_id, callConfig);
 
219
    setIPToIPForCall(call_id, IPToIP);
221
220
 
222
221
    // in any cases we have to detach from current communication
223
222
    if (hasCurrentCall()) {
230
229
            detachParticipant(Call::DEFAULT_ID, current_call_id);
231
230
    }
232
231
 
233
 
    if (callConfig == Call::IPtoIP) {
 
232
    if (IPToIP) {
234
233
        DEBUG("Manager: Start IP2IP call");
235
234
 
236
235
        /* We need to retrieve the sip voiplink instance */
340
339
//THREAD=Main
341
340
void ManagerImpl::hangupCall(const std::string& callId)
342
341
{
343
 
    INFO("Manager: Hangup call %s", callId.c_str());
 
342
    DEBUG("Manager: Hangup call %s", callId.c_str());
344
343
 
345
344
    // store the current call id
346
345
    std::string currentCallId(getCurrentCallId());
351
350
    DEBUG("Manager: Send DBUS call state change (HUNGUP) for id %s", callId.c_str());
352
351
    dbus_.getCallManager()->callStateChanged(callId, "HUNGUP");
353
352
 
354
 
    if (not isValidCall(callId) and not getConfigFromCall(callId) == Call::IPtoIP) {
 
353
    if (not isValidCall(callId) and not isIPToIP(callId)) {
355
354
        ERROR("Manager: Error: Could not hang up call, call not valid");
356
355
        return;
357
356
    }
373
372
            switchCall("");
374
373
    }
375
374
 
376
 
    if (getConfigFromCall(callId) == Call::IPtoIP) {
 
375
    if (isIPToIP(callId)) {
377
376
        /* Direct IP to IP call */
378
377
        try {
 
378
            Call * call = SIPVoIPLink::instance()->getCall(callId);
 
379
            history_->addCall(call, preferences.getHistoryLimit());
379
380
            SIPVoIPLink::instance()->hangup(callId);
380
381
        } catch (const VoipLinkException &e) {
381
382
            ERROR("%s", e.what());
382
383
        }
383
384
    } else {
384
385
        std::string accountId(getAccountFromCall(callId));
385
 
        getAccountLink(accountId)->hangup(callId);
 
386
        VoIPLink *link = getAccountLink(accountId);
 
387
        Call * call = link->getCall(callId);
 
388
        history_->addCall(call, preferences.getHistoryLimit());
 
389
        link->hangup(callId);
386
390
        removeCallAccount(callId);
387
391
    }
388
392
 
428
432
    std::string current_call_id(getCurrentCallId());
429
433
 
430
434
    try {
431
 
        if (getConfigFromCall(callId) == Call::IPtoIP) {
432
 
            /* Direct IP to IP call */
 
435
        if (isIPToIP(callId)) {
433
436
            SIPVoIPLink::instance()-> onhold(callId);
434
437
        } else {
435
438
            /* Classic call, attached to an account */
487
490
 
488
491
    bool isRec = false;
489
492
 
490
 
    /* Direct IP to IP call */
491
 
    if (getConfigFromCall(callId) == Call::IPtoIP)
492
 
        SIPVoIPLink::instance()-> offhold(callId);
 
493
    if (isIPToIP(callId))
 
494
        SIPVoIPLink::instance()->offhold(callId);
493
495
    else {
494
496
        /* Classic call, attached to an account */
495
497
        accountId = getAccountFromCall(callId);
532
534
        switchCall("");
533
535
 
534
536
    // Direct IP to IP call
535
 
    if (getConfigFromCall(callId) == Call::IPtoIP)
 
537
    if (isIPToIP(callId)) {
536
538
        SIPVoIPLink::instance()->transfer(callId, to);
537
 
    else {
538
 
        std::string accountid(getAccountFromCall(callId));
 
539
    } else {
 
540
        std::string accountID(getAccountFromCall(callId));
539
541
 
540
 
        if (accountid.empty())
 
542
        if (accountID.empty())
541
543
            return false;
542
544
 
543
 
        getAccountLink(accountid)->transfer(callId, to);
 
545
        VoIPLink *link = getAccountLink(accountID);
 
546
        link->transfer(callId, to);
544
547
    }
545
548
 
546
549
    // remove waiting call in case we make transfer without even answer
556
559
    dbus_.getCallManager()->transferFailed();
557
560
}
558
561
 
559
 
void ManagerImpl::transferSucceded()
 
562
void ManagerImpl::transferSucceeded()
560
563
{
561
 
    dbus_.getCallManager()->transferSucceded();
 
564
    dbus_.getCallManager()->transferSucceeded();
562
565
}
563
566
 
564
567
bool ManagerImpl::attendedTransfer(const std::string& transferID, const std::string& targetID)
565
568
{
566
 
    if (getConfigFromCall(transferID) == Call::IPtoIP)
 
569
    if (isIPToIP(transferID))
567
570
        return SIPVoIPLink::instance()->attendedTransfer(transferID, targetID);
568
571
 
569
572
    // Classic call, attached to an account
581
584
    stopTone();
582
585
 
583
586
    if (getCallList().size() <= 1) {
584
 
        audioLayerMutexLock();
 
587
        ost::MutexLock lock(audioLayerMutex_);
585
588
        audiodriver_->stopStream();
586
 
        audioLayerMutexUnlock();
587
589
    }
588
590
 
589
591
    /* Direct IP to IP call */
590
592
 
591
 
    if (getConfigFromCall(id) == Call::IPtoIP)
 
593
    if (isIPToIP(id))
592
594
        SIPVoIPLink::instance()->refuse(id);
593
595
    else {
594
596
        /* Classic call, attached to an account */
633
635
void ManagerImpl::removeConference(const std::string& conference_id)
634
636
{
635
637
    DEBUG("Manager: Remove conference %s", conference_id.c_str());
636
 
 
637
638
    DEBUG("Manager: number of participants: %u", conferenceMap_.size());
638
639
    ConferenceMap::iterator iter = conferenceMap_.find(conference_id);
639
640
 
816
817
 
817
818
    // reset ring buffer for all conference participant
818
819
    // flush conference participants only
819
 
    for (ParticipantSet::const_iterator iter_p = participants.begin();
820
 
            iter_p != participants.end(); ++iter_p)
821
 
        getMainBuffer()->flush(*iter_p);
 
820
    for (ParticipantSet::const_iterator p = participants.begin();
 
821
            p != participants.end(); ++p)
 
822
        getMainBuffer()->flush(*p);
822
823
 
823
824
    getMainBuffer()->flush(Call::DEFAULT_ID);
824
825
 
837
838
            onHoldCall(current_call_id);
838
839
    }
839
840
 
840
 
    audioLayerMutexLock();
841
 
 
842
 
    ConferenceMap::const_iterator iter = conferenceMap_.find(conference_id);
843
 
 
844
 
    if (iter != conferenceMap_.end()) {
845
 
        Conference *conf = iter->second;
 
841
    {
 
842
        ost::MutexLock lock(audioLayerMutex_);
 
843
 
 
844
        ConferenceMap::const_iterator iter = conferenceMap_.find(conference_id);
 
845
 
 
846
        if (iter != conferenceMap_.end()) {
 
847
            Conference *conf = iter->second;
846
848
 
847
849
        ParticipantSet participants(conf->getParticipantList());
848
850
 
863
865
            WARN("Manager: Warning: Invalid conference state while adding main participant");
864
866
 
865
867
        dbus_.getCallManager()->conferenceChanged(conference_id, conf->getStateStr());
 
868
        }
866
869
    }
867
870
 
868
 
    audioLayerMutexUnlock();
869
 
 
870
871
    switchCall(conference_id);
871
872
}
872
873
 
960
961
    conf->setState(Conference::ACTIVE_ATTACHED);
961
962
 
962
963
    // set recording sampling rate
963
 
    audioLayerMutexLock();
964
 
 
965
 
    if (audiodriver_)
966
 
        conf->setRecordingSmplRate(audiodriver_->getSampleRate());
967
 
 
968
 
    audioLayerMutexUnlock();
 
964
    {
 
965
        ost::MutexLock lock(audioLayerMutex_);
 
966
        if (audiodriver_)
 
967
            conf->setRecordingSmplRate(audiodriver_->getSampleRate());
 
968
    }
969
969
 
970
970
    getMainBuffer()->stateInfo();
971
971
}
982
982
 
983
983
    int successCounter = 0;
984
984
 
985
 
    for (std::vector<std::string>::const_iterator iter = participantList.begin(); iter != participantList.end(); ++iter) {
986
 
        std::string numberaccount(*iter);
 
985
    for (std::vector<std::string>::const_iterator p = participantList.begin();
 
986
         p != participantList.end(); ++p) {
 
987
        std::string numberaccount(*p);
987
988
        std::string tostr(numberaccount.substr(0, numberaccount.find(",")));
988
989
        std::string account(numberaccount.substr(numberaccount.find(",") + 1, numberaccount.size()));
989
990
 
1011
1012
        conferenceMap_.insert(std::make_pair(conf->getConfID(), conf));
1012
1013
        dbus_.getCallManager()->conferenceCreated(conf->getConfID());
1013
1014
 
1014
 
        audioLayerMutexLock();
1015
 
 
1016
 
        if (audiodriver_)
1017
 
            conf->setRecordingSmplRate(audiodriver_->getSampleRate());
1018
 
 
1019
 
        audioLayerMutexUnlock();
 
1015
        {
 
1016
            ost::MutexLock lock(audioLayerMutex_);
 
1017
 
 
1018
            if (audiodriver_)
 
1019
                conf->setRecordingSmplRate(audiodriver_->getSampleRate());
 
1020
        }
1020
1021
 
1021
1022
        getMainBuffer()->stateInfo();
1022
1023
    } else
1134
1135
 
1135
1136
    if (n > 1) {
1136
1137
        // Reset ringbuffer's readpointers
1137
 
        for (ParticipantSet::const_iterator iter_p = participants.begin();
1138
 
                iter_p != participants.end();
1139
 
                ++iter_p)
1140
 
            getMainBuffer()->flush(*iter_p);
 
1138
        for (ParticipantSet::const_iterator p = participants.begin();
 
1139
             p != participants.end(); ++p)
 
1140
            getMainBuffer()->flush(*p);
1141
1141
 
1142
1142
        getMainBuffer()->flush(Call::DEFAULT_ID);
1143
1143
    } else if (n == 1) {
1144
 
        ParticipantSet::iterator iter_participant = participants.begin();
 
1144
        ParticipantSet::iterator p = participants.begin();
1145
1145
 
1146
1146
        // bind main participant to remaining conference call
1147
 
        if (iter_participant != participants.end()) {
 
1147
        if (p != participants.end()) {
1148
1148
            // this call is no longer a conference participant
1149
 
            std::string currentAccountId(getAccountFromCall(*iter_participant));
1150
 
            Call *call = getAccountLink(currentAccountId)->getCall(*iter_participant);
 
1149
            std::string currentAccountId(getAccountFromCall(*p));
 
1150
            Call *call = getAccountLink(currentAccountId)->getCall(*p);
1151
1151
            if (call) {
1152
1152
                call->setConfId("");
1153
1153
                // if we are not listening to this conference
1154
1154
                if (current_call_id != conf->getConfID())
1155
1155
                    onHoldCall(call->getCallId());
1156
1156
                else
1157
 
                    switchCall(*iter_participant);
 
1157
                    switchCall(*p);
1158
1158
            }
1159
1159
        }
1160
1160
 
1187
1187
        Conference *conf = iter->second;
1188
1188
        ParticipantSet participants(conf->getParticipantList());
1189
1189
 
1190
 
        for (ParticipantSet::const_iterator iter_p = participants.begin();
1191
 
                iter_p != participants.end(); ++iter_p) {
1192
 
            detachParticipant(*iter_p, "");
1193
 
            addParticipant(*iter_p, conf_id2);
 
1190
        for (ParticipantSet::const_iterator p = participants.begin();
 
1191
                p != participants.end(); ++p) {
 
1192
            detachParticipant(*p, "");
 
1193
            addParticipant(*p, conf_id2);
1194
1194
        }
1195
1195
    }
1196
1196
}
1229
1229
        // bind to main
1230
1230
        getMainBuffer()->bindCallID(call_id);
1231
1231
 
1232
 
        audioLayerMutexLock();
 
1232
        ost::MutexLock lock(audioLayerMutex_);
1233
1233
        audiodriver_->flushUrgent();
1234
1234
        audiodriver_->flushMain();
1235
 
        audioLayerMutexUnlock();
1236
1235
    }
1237
1236
 
1238
1237
    getMainBuffer()->stateInfo();
1302
1301
        return;
1303
1302
    }
1304
1303
 
1305
 
    audioLayerMutexLock();
 
1304
    ost::MutexLock lock(audioLayerMutex_);
1306
1305
 
1307
1306
    // numbers of int = length in milliseconds / 1000 (number of seconds)
1308
1307
    //                = number of seconds * SAMPLING_RATE by SECONDS
1310
1309
    // fast return, no sound, so no dtmf
1311
1310
    if (audiodriver_ == NULL || dtmfKey_ == NULL) {
1312
1311
        DEBUG("Manager: playDtmf: Error no audio layer...");
1313
 
        audioLayerMutexUnlock();
1314
1312
        return;
1315
1313
    }
1316
1314
 
1337
1335
        audiodriver_->putUrgent(buf, size * sizeof(SFLDataFormat));
1338
1336
    }
1339
1337
 
1340
 
    audioLayerMutexUnlock();
1341
 
 
1342
1338
    // TODO Cache the DTMF
1343
1339
 
1344
1340
    delete [] buf;
1345
1341
}
1346
1342
 
1347
1343
// Multi-thread
1348
 
bool ManagerImpl::incomingCallWaiting()
 
1344
bool ManagerImpl::incomingCallWaiting() const
1349
1345
{
1350
1346
    return nbIncomingWaitingCall_ > 0;
1351
1347
}
1365
1361
        nbIncomingWaitingCall_--;
1366
1362
}
1367
1363
 
1368
 
bool ManagerImpl::isWaitingCall(const std::string& id)
 
1364
bool ManagerImpl::isWaitingCall(const std::string &id) const
1369
1365
{
1370
1366
    return waitingCall_.find(id) != waitingCall_.end();
1371
1367
}
1382
1378
    associateCallToAccount(call->getCallId(), accountId);
1383
1379
 
1384
1380
    if (accountId.empty())
1385
 
        associateConfigToCall(call->getCallId(), Call::IPtoIP);
 
1381
        setIPToIPForCall(call->getCallId(), true);
1386
1382
    else {
1387
1383
        // strip sip: which is not required and bring confusion with ip to ip calls
1388
1384
        // when placing new call from history (if call is IAX, do nothing)
1389
1385
        std::string peerNumber(call->getPeerNumber());
1390
1386
 
1391
 
        size_t startIndex = peerNumber.find("sip:");
 
1387
        const char SIP_PREFIX[] = "sip:";
 
1388
        size_t startIndex = peerNumber.find(SIP_PREFIX);
1392
1389
 
1393
1390
        if (startIndex != std::string::npos)
1394
 
            call->setPeerNumber(peerNumber.substr(startIndex + 4));
 
1391
            call->setPeerNumber(peerNumber.substr(startIndex + sizeof(SIP_PREFIX) - 1));
1395
1392
    }
1396
1393
 
1397
1394
    if (not hasCurrentCall()) {
1398
 
        call->setConnectionState(Call::Ringing);
 
1395
        call->setConnectionState(Call::RINGING);
1399
1396
        ringtone(accountId);
1400
1397
    }
1401
1398
 
1402
1399
    addWaitingCall(call->getCallId());
1403
1400
 
1404
 
    std::string from(call->getPeerName());
1405
1401
    std::string number(call->getPeerNumber());
1406
1402
 
1407
 
    if (not from.empty() and not number.empty())
1408
 
        from += " ";
1409
 
 
1410
 
    from += "<" + number + ">";
1411
 
 
 
1403
    std::string from("<" + number + ">");
1412
1404
    dbus_.getCallManager()->incomingCall(accountId, call->getCallId(), call->getDisplayName() + " " + from);
1413
1405
}
1414
1406
 
1535
1527
    // Connect audio streams
1536
1528
    addStream(id);
1537
1529
 
1538
 
    audioLayerMutexLock();
1539
 
    audiodriver_->flushMain();
1540
 
    audiodriver_->flushUrgent();
1541
 
    audioLayerMutexUnlock();
 
1530
    {
 
1531
        ost::MutexLock lock(audioLayerMutex_);
 
1532
        audiodriver_->flushMain();
 
1533
        audiodriver_->flushUrgent();
 
1534
    }
1542
1535
 
1543
1536
    if (audioPreference.getIsAlwaysRecording()) {
1544
1537
        setRecordingCall(id);
1578
1571
    }
1579
1572
 
1580
1573
    /* Direct IP to IP call */
1581
 
    if (getConfigFromCall(call_id) == Call::IPtoIP)
 
1574
    if (isIPToIP(call_id)) {
 
1575
        Call * call = SIPVoIPLink::instance()->getCall(call_id);
 
1576
        history_->addCall(call, preferences.getHistoryLimit());
1582
1577
        SIPVoIPLink::instance()->hangup(call_id);
 
1578
    }
1583
1579
    else {
1584
1580
        const std::string account_id(getAccountFromCall(call_id));
1585
 
        getAccountLink(account_id)->peerHungup(call_id);
 
1581
        VoIPLink *link = getAccountLink(account_id);
 
1582
        Call * call = link->getCall(call_id);
 
1583
        history_->addCall(call, preferences.getHistoryLimit());
 
1584
        link->peerHungup(call_id);
1586
1585
    }
1587
1586
 
1588
1587
    /* Broadcast a signal over DBus */
1594
1593
 
1595
1594
    if (getCallList().empty()) {
1596
1595
        DEBUG("Manager: Stop audio stream, there are no calls remaining");
1597
 
 
1598
 
        audioLayerMutexLock();
 
1596
        ost::MutexLock lock(audioLayerMutex_);
1599
1597
        audiodriver_->stopStream();
1600
 
        audioLayerMutexUnlock();
1601
1598
    }
1602
1599
}
1603
1600
 
1664
1661
    if (not voipPreferences.getPlayTones())
1665
1662
        return;
1666
1663
 
1667
 
    audioLayerMutexLock();
1668
 
 
1669
 
    if (audiodriver_ == NULL) {
1670
 
        ERROR("Manager: Error: Audio layer not initialized");
1671
 
        audioLayerMutexUnlock();
1672
 
        return;
 
1664
    {
 
1665
        ost::MutexLock lock(audioLayerMutex_);
 
1666
 
 
1667
        if (audiodriver_ == NULL) {
 
1668
            ERROR("Manager: Error: Audio layer not initialized");
 
1669
            return;
 
1670
        }
 
1671
 
 
1672
        audiodriver_->flushUrgent();
 
1673
        audiodriver_->startStream();
1673
1674
    }
1674
1675
 
1675
 
    audiodriver_->flushUrgent();
1676
 
    audiodriver_->startStream();
1677
 
    audioLayerMutexUnlock();
1678
 
 
1679
1676
    if (telephoneTone_ != 0) {
1680
 
        toneMutex_.enterMutex();
 
1677
        ost::MutexLock lock(toneMutex_);
1681
1678
        telephoneTone_->setCurrentTone(toneId);
1682
 
        toneMutex_.leaveMutex();
1683
1679
    }
1684
1680
}
1685
1681
 
1691
1687
    if (not voipPreferences.getPlayTones())
1692
1688
        return;
1693
1689
 
1694
 
    toneMutex_.enterMutex();
 
1690
    ost::MutexLock lock(toneMutex_);
1695
1691
 
1696
1692
    if (telephoneTone_ != NULL)
1697
1693
        telephoneTone_->setCurrentTone(Tone::TONE_NULL);
1702
1698
        delete audiofile_;
1703
1699
        audiofile_ = NULL;
1704
1700
    }
1705
 
 
1706
 
    toneMutex_.leaveMutex();
1707
1701
}
1708
1702
 
1709
1703
/**
1764
1758
                     + RINGDIR + DIR_SEPARATOR_STR + ringchoice;
1765
1759
    }
1766
1760
 
1767
 
    audioLayerMutexLock();
1768
 
 
1769
 
    if (!audiodriver_) {
1770
 
        ERROR("Manager: Error: no audio layer in ringtone");
1771
 
        audioLayerMutexUnlock();
1772
 
        return;
 
1761
    int samplerate;
 
1762
    {
 
1763
        ost::MutexLock lock(audioLayerMutex_);
 
1764
 
 
1765
        if (!audiodriver_) {
 
1766
            ERROR("Manager: Error: no audio layer in ringtone");
 
1767
            return;
 
1768
        }
 
1769
 
 
1770
        samplerate = audiodriver_->getSampleRate();
1773
1771
    }
1774
1772
 
1775
 
    int samplerate = audiodriver_->getSampleRate();
1776
 
 
1777
 
    audioLayerMutexUnlock();
1778
 
 
1779
1773
    {
1780
1774
        ost::MutexLock m(toneMutex_);
1781
1775
 
1803
1797
        }
1804
1798
    } // leave mutex
1805
1799
 
1806
 
    audioLayerMutexLock();
 
1800
    ost::MutexLock lock(audioLayerMutex_);
1807
1801
    // start audio if not started AND flush all buffers (main and urgent)
1808
1802
    audiodriver_->startStream();
1809
 
    audioLayerMutexUnlock();
1810
1803
}
1811
1804
 
1812
1805
AudioLoop*
1846
1839
    }
1847
1840
 
1848
1841
    if (mkdir(configdir.data(), 0700) != 0) {
1849
 
        // If directory creation failed
 
1842
        // If directory creation failed
1850
1843
        if (errno != EEXIST)
1851
 
            DEBUG("Cannot create directory: %m");
 
1844
           DEBUG("Cannot create directory: %m");
1852
1845
    }
1853
1846
 
1854
1847
    static const char * const PROGNAME = "sflphoned";
1872
1865
 
1873
1866
std::string ManagerImpl::serialize(const std::vector<std::string> &v)
1874
1867
{
1875
 
    std::string res;
1876
 
 
1877
 
    for (std::vector<std::string>::const_iterator iter = v.begin(); iter != v.end(); ++iter)
1878
 
        res += *iter + "/";
1879
 
 
1880
 
    return res;
 
1868
    std::ostringstream os;
 
1869
    std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(os, "/"));
 
1870
    return os.str();
1881
1871
}
1882
1872
 
1883
1873
std::string ManagerImpl::getCurrentCodecName(const std::string& id)
1890
1880
    if (call) {
1891
1881
        Call::CallState state = call->getState();
1892
1882
 
1893
 
        if (state == Call::Active or state == Call::Conferencing)
 
1883
        if (state == Call::ACTIVE or state == Call::CONFERENCING)
1894
1884
            codecName = link->getCurrentCodecName(call);
1895
1885
    }
1896
1886
 
1902
1892
 */
1903
1893
void ManagerImpl::setAudioPlugin(const std::string& audioPlugin)
1904
1894
{
1905
 
    audioLayerMutexLock();
 
1895
    ost::MutexLock lock(audioLayerMutex_);
1906
1896
 
1907
1897
    audioPreference.setPlugin(audioPlugin);
1908
1898
 
1910
1900
 
1911
1901
    if (!alsa) {
1912
1902
        ERROR("Can't find alsa device");
1913
 
        audioLayerMutexUnlock();
1914
 
        return ;
 
1903
        return;
1915
1904
    }
1916
1905
 
1917
1906
    bool wasStarted = audiodriver_->isStarted();
1922
1911
 
1923
1912
    if (wasStarted)
1924
1913
        audiodriver_->startStream();
1925
 
 
1926
 
    audioLayerMutexUnlock();
1927
1914
}
1928
1915
 
1929
1916
/**
1931
1918
 */
1932
1919
void ManagerImpl::setAudioDevice(const int index, int streamType)
1933
1920
{
1934
 
    audioLayerMutexLock();
 
1921
    ost::MutexLock lock(audioLayerMutex_);
1935
1922
 
1936
1923
    AlsaLayer *alsaLayer = dynamic_cast<AlsaLayer*>(audiodriver_);
1937
1924
 
1938
1925
    if (!alsaLayer) {
1939
1926
        ERROR("Can't find alsa device");
1940
 
        audioLayerMutexUnlock();
1941
1927
        return ;
1942
1928
    }
1943
1929
 
1963
1949
 
1964
1950
    if (wasStarted)
1965
1951
        audiodriver_->startStream();
1966
 
 
1967
 
    audioLayerMutexUnlock();
1968
1952
}
1969
1953
 
1970
1954
/**
1974
1958
{
1975
1959
    std::vector<std::string> devices;
1976
1960
 
1977
 
    audioLayerMutexLock();
 
1961
    ost::MutexLock lock(audioLayerMutex_);
1978
1962
 
1979
1963
    AlsaLayer *alsalayer = dynamic_cast<AlsaLayer*>(audiodriver_);
1980
1964
 
1981
1965
    if (alsalayer)
1982
 
        devices = alsalayer->getSoundCardsInfo(SFL_PCM_PLAYBACK);
1983
 
 
1984
 
    audioLayerMutexUnlock();
 
1966
        devices = alsalayer->getAudioDeviceList(AUDIO_STREAM_PLAYBACK);
1985
1967
 
1986
1968
    return devices;
1987
1969
}
1994
1976
{
1995
1977
    std::vector<std::string> devices;
1996
1978
 
1997
 
    audioLayerMutexLock();
 
1979
    ost::MutexLock lock(audioLayerMutex_);
1998
1980
 
1999
1981
    AlsaLayer *alsalayer = dynamic_cast<AlsaLayer *>(audiodriver_);
2000
1982
 
2001
1983
    if (alsalayer)
2002
 
        devices = alsalayer->getSoundCardsInfo(SFL_PCM_CAPTURE);
2003
 
 
2004
 
    audioLayerMutexUnlock();
 
1984
        devices = alsalayer->getAudioDeviceList(AUDIO_STREAM_CAPTURE);
2005
1985
 
2006
1986
    return devices;
2007
1987
}
2011
1991
 */
2012
1992
std::vector<std::string> ManagerImpl::getCurrentAudioDevicesIndex()
2013
1993
{
2014
 
    audioLayerMutexLock();
 
1994
    ost::MutexLock lock(audioLayerMutex_);
2015
1995
 
2016
1996
    std::vector<std::string> v;
2017
1997
 
2019
1999
 
2020
2000
    if (alsa) {
2021
2001
        std::stringstream ssi, sso, ssr;
2022
 
        sso << alsa->getIndexOut();
 
2002
        sso << alsa->getIndexPlayback();
2023
2003
        v.push_back(sso.str());
2024
 
        ssi << alsa->getIndexIn();
 
2004
        ssi << alsa->getIndexCapture();
2025
2005
        v.push_back(ssi.str());
2026
 
        ssr << alsa->getIndexRing();
 
2006
        ssr << alsa->getIndexRingtone();
2027
2007
        v.push_back(ssr.str());
2028
2008
    }
2029
2009
 
2030
 
    audioLayerMutexUnlock();
2031
 
 
2032
2010
    return v;
2033
2011
}
2034
2012
 
2105
2083
    }
2106
2084
 
2107
2085
    rec->setRecording();
2108
 
    dbus_.getCallManager()->recordPlaybackFilepath(id, rec->getFileName());
 
2086
    dbus_.getCallManager()->recordPlaybackFilepath(id, rec->getFilename());
2109
2087
}
2110
2088
 
2111
2089
bool ManagerImpl::isRecording(const std::string& id)
2119
2097
{
2120
2098
    DEBUG("Manager: Start recorded file playback %s", filepath.c_str());
2121
2099
 
2122
 
    audioLayerMutexLock();
2123
 
 
2124
 
    if (!audiodriver_) {
2125
 
        ERROR("Manager: Error: No audio layer in start recorded file playback");
2126
 
        audioLayerMutexUnlock();
2127
 
        return false;
 
2100
    int sampleRate;
 
2101
    {
 
2102
        ost::MutexLock lock(audioLayerMutex_);
 
2103
 
 
2104
        if (!audiodriver_) {
 
2105
            ERROR("Manager: Error: No audio layer in start recorded file playback");
 
2106
            return false;
 
2107
        }
 
2108
 
 
2109
        sampleRate = audiodriver_->getSampleRate();
2128
2110
    }
2129
2111
 
2130
 
    int sampleRate = audiodriver_->getSampleRate();
2131
 
 
2132
 
    audioLayerMutexUnlock();
2133
 
 
2134
2112
    {
2135
2113
        ost::MutexLock m(toneMutex_);
2136
2114
 
2147
2125
        }
2148
2126
    } // release toneMutex
2149
2127
 
2150
 
    audioLayerMutexLock();
 
2128
    ost::MutexLock lock(audioLayerMutex_);
2151
2129
    audiodriver_->startStream();
2152
 
    audioLayerMutexUnlock();
2153
2130
 
2154
2131
    return true;
2155
2132
}
2159
2136
{
2160
2137
    DEBUG("Manager: Stop recorded file playback %s", filepath.c_str());
2161
2138
 
2162
 
    audioLayerMutexLock();
2163
 
    audiodriver_->stopStream();
2164
 
    audioLayerMutexUnlock();
 
2139
    {
 
2140
        ost::MutexLock lock(audioLayerMutex_);
 
2141
        audiodriver_->stopStream();
 
2142
    }
2165
2143
 
2166
2144
    {
2167
2145
        ost::MutexLock m(toneMutex_);
2196
2174
 
2197
2175
void ManagerImpl::setAudioManager(const std::string &api)
2198
2176
{
2199
 
    audioLayerMutexLock();
2200
 
 
2201
 
    if (!audiodriver_) {
2202
 
        audioLayerMutexUnlock();
2203
 
        return;
2204
 
    }
2205
 
 
2206
 
    if (api == audioPreference.getAudioApi()) {
2207
 
        DEBUG("Manager: Audio manager chosen already in use. No changes made. ");
2208
 
        audioLayerMutexUnlock();
2209
 
        return;
2210
 
    }
2211
 
 
2212
 
    audioLayerMutexUnlock();
 
2177
    {
 
2178
        ost::MutexLock lock(audioLayerMutex_);
 
2179
 
 
2180
        if (!audiodriver_)
 
2181
            return;
 
2182
 
 
2183
        if (api == audioPreference.getAudioApi()) {
 
2184
            DEBUG("Manager: Audio manager chosen already in use. No changes made. ");
 
2185
            return;
 
2186
        }
 
2187
    }
2213
2188
 
2214
2189
    switchAudioManager();
2215
2190
 
2226
2201
{
2227
2202
    int soundCardIndex = 0;
2228
2203
 
2229
 
    audioLayerMutexLock();
 
2204
    ost::MutexLock lock(audioLayerMutex_);
2230
2205
 
2231
2206
    if (audiodriver_ == NULL) {
2232
2207
        ERROR("Manager: Error: Audio layer not initialized");
2233
 
        audioLayerMutexUnlock();
2234
2208
        return soundCardIndex;
2235
2209
    }
2236
2210
 
2237
2211
    AlsaLayer *alsalayer = dynamic_cast<AlsaLayer *>(audiodriver_);
2238
2212
 
2239
2213
    if (alsalayer)
2240
 
        soundCardIndex = alsalayer -> soundCardGetIndex(name);
2241
 
 
2242
 
    audioLayerMutexUnlock();
 
2214
        soundCardIndex = alsalayer -> getAudioDeviceIndex(name);
2243
2215
 
2244
2216
    return soundCardIndex;
2245
2217
}
2295
2267
 */
2296
2268
void ManagerImpl::initAudioDriver()
2297
2269
{
2298
 
    audioLayerMutexLock();
 
2270
    ost::MutexLock lock(audioLayerMutex_);
2299
2271
    audiodriver_ = audioPreference.createAudioLayer();
2300
 
 
2301
 
    audioLayerMutexUnlock();
2302
2272
}
2303
2273
 
2304
2274
void ManagerImpl::switchAudioManager()
2305
2275
{
2306
 
    audioLayerMutexLock();
 
2276
    ost::MutexLock lock(audioLayerMutex_);
2307
2277
 
2308
2278
    bool wasStarted = audiodriver_->isStarted();
2309
2279
    delete audiodriver_;
2311
2281
 
2312
2282
    if (wasStarted)
2313
2283
        audiodriver_->startStream();
2314
 
 
2315
 
    audioLayerMutexUnlock();
2316
2284
}
2317
2285
 
2318
2286
void ManagerImpl::audioSamplingRateChanged(int samplerate)
2319
2287
{
2320
 
    audioLayerMutexLock();
 
2288
    ost::MutexLock lock(audioLayerMutex_);
2321
2289
 
2322
2290
    if (!audiodriver_) {
2323
2291
        DEBUG("Manager: No Audio driver initialized");
2324
 
        audioLayerMutexUnlock();
2325
2292
        return;
2326
2293
    }
2327
2294
 
2330
2297
 
2331
2298
    if (currentSamplerate >= samplerate) {
2332
2299
        DEBUG("Manager: No need to update audio layer sampling rate");
2333
 
        audioLayerMutexUnlock();
2334
2300
        return;
2335
2301
    } else
2336
2302
        DEBUG("Manager: Audio sampling rate changed: %d -> %d", currentSamplerate, samplerate);
2352
2318
 
2353
2319
    if (wasActive)
2354
2320
        audiodriver_->startStream();
2355
 
 
2356
 
    audioLayerMutexUnlock();
2357
2321
}
2358
2322
 
2359
2323
/**
2381
2345
    return preferences.getPortNum();
2382
2346
}
2383
2347
 
2384
 
 
2385
2348
//THREAD=Main
2386
2349
bool ManagerImpl::getConfig(const std::string& section,
2387
2350
                            const std::string& name, TokenList& arg) const
2390
2353
}
2391
2354
 
2392
2355
//THREAD=Main
2393
 
// throw an Conf::ConfigTreeItemException if not found
2394
2356
int ManagerImpl::getConfigInt(const std::string& section,
2395
2357
                              const std::string& name) const
2396
2358
{
2411
2373
}
2412
2374
 
2413
2375
//THREAD=Main
2414
 
bool ManagerImpl::setConfig(const std::string& section,
 
2376
void ManagerImpl::setConfig(const std::string& section,
2415
2377
                            const std::string& name, const std::string& value)
2416
2378
{
2417
 
    return config_.setConfigTreeItem(section, name, value);
 
2379
    config_.setConfigTreeItem(section, name, value);
2418
2380
}
2419
2381
 
2420
2382
//THREAD=Main
2421
 
bool ManagerImpl::setConfig(const std::string& section,
 
2383
void ManagerImpl::setConfig(const std::string& section,
2422
2384
                            const std::string& name, int value)
2423
2385
{
2424
2386
    std::ostringstream valueStream;
2425
2387
    valueStream << value;
2426
 
    return config_.setConfigTreeItem(section, name, valueStream.str());
 
2388
    config_.setConfigTreeItem(section, name, valueStream.str());
2427
2389
}
2428
2390
 
2429
2391
void ManagerImpl::setAccountsOrder(const std::string& order)
2550
2512
 
2551
2513
    if (accountType == "SIP")
2552
2514
        newAccount = new SIPAccount(newAccountID);
 
2515
#if HAVE_IAX
2553
2516
    else if (accountType == "IAX")
2554
2517
        newAccount = new IAXAccount(newAccountID);
 
2518
#endif
2555
2519
    else {
2556
2520
        ERROR("Unknown %s param when calling addAccount(): %s",
2557
2521
               CONFIG_ACCOUNT_TYPE, accountType.c_str());
2565
2529
    // Add the newly created account in the account order list
2566
2530
    std::string accountList(preferences.getAccountOrder());
2567
2531
 
 
2532
    newAccountID += "/";
2568
2533
    if (not accountList.empty()) {
2569
 
        newAccountID += "/";
2570
2534
        // Prepend the new account
2571
2535
        accountList.insert(0, newAccountID);
2572
2536
        preferences.setAccountOrder(accountList);
2573
2537
    } else {
2574
 
        newAccountID += "/";
2575
2538
        accountList = newAccountID;
2576
2539
        preferences.setAccountOrder(accountList);
2577
2540
    }
2636
2599
 
2637
2600
    // Stop audio layer if there is no call anymore
2638
2601
    if (callAccountMap_.empty()) {
2639
 
        audioLayerMutexLock();
 
2602
        ost::MutexLock lock(audioLayerMutex_);
2640
2603
 
2641
2604
        if (audiodriver_)
2642
2605
            audiodriver_->stopStream();
2643
 
 
2644
 
        audioLayerMutexUnlock();
2645
2606
    }
2646
2607
 
2647
2608
}
2735
2696
 
2736
2697
        Account *a;
2737
2698
 
 
2699
#if HAVE_IAX
2738
2700
        if (accountType == "IAX")
2739
2701
            a = new IAXAccount(accountid);
2740
2702
        else // assume SIP
 
2703
#endif
2741
2704
            a = new SIPAccount(accountid);
2742
2705
 
2743
2706
        accountMap_[accountid] = a;
2776
2739
 
2777
2740
std::string ManagerImpl::getAccountIdFromNameAndServer(const std::string& userName, const std::string& server) const
2778
2741
{
2779
 
    INFO("Manager : username = %s, server = %s", userName.c_str(), server.c_str());
 
2742
    DEBUG("Manager : username = %s, server = %s", userName.c_str(), server.c_str());
2780
2743
    // Try to find the account id from username and server name by full match
2781
2744
 
2782
2745
    for (AccountMap::const_iterator iter = accountMap_.begin(); iter != accountMap_.end(); ++iter) {
2835
2798
    addressbookPreference.setBusiness(settings.find("ADDRESSBOOK_DISPLAY_PHONE_BUSINESS")->second == 1);
2836
2799
    addressbookPreference.setHone(settings.find("ADDRESSBOOK_DISPLAY_PHONE_HOME")->second == 1);
2837
2800
    addressbookPreference.setMobile(settings.find("ADDRESSBOOK_DISPLAY_PHONE_MOBILE")->second == 1);
2838
 
 
2839
 
    // Write it to the configuration file
2840
 
    // TODO save config is called for updateAddressbookSettings, updateHookSettings, setHistoryLimit each called
2841
 
    // when closing preference window (in this order)
2842
 
    // saveConfig();
2843
2801
}
2844
2802
 
2845
2803
void ManagerImpl::setAddressbookList(const std::vector<std::string>& list)
2875
2833
    hookPreference.setSipEnabled(settings.find("URLHOOK_SIP_ENABLED")->second == "true");
2876
2834
    hookPreference.setUrlCommand(settings.find("URLHOOK_COMMAND")->second);
2877
2835
    hookPreference.setUrlSipField(settings.find("URLHOOK_SIP_FIELD")->second);
2878
 
 
2879
 
    // Write it to the configuration file
2880
 
    // TODO save config is called for updateAddressbookSettings, updateHookSettings, setHistoryLimit each called
2881
 
    // when closing preference window (in this order)
2882
 
    // saveConfig();
2883
 
}
2884
 
 
2885
 
bool ManagerImpl::associateConfigToCall(const std::string& callID,
2886
 
                                        Call::CallConfiguration config)
2887
 
{
2888
 
    if (getConfigFromCall(callID) == 0) {  // nothing with the same ID
2889
 
        callConfigMap_[callID] = config;
2890
 
        DEBUG("Manager: Associate call %s with config %d", callID.c_str(), config);
2891
 
        return true;
2892
 
    } else
2893
 
        return false;
2894
 
}
2895
 
 
2896
 
Call::CallConfiguration ManagerImpl::getConfigFromCall(const std::string& callID) const
2897
 
{
2898
 
    CallConfigMap::const_iterator iter = callConfigMap_.find(callID);
2899
 
 
2900
 
    if (iter == callConfigMap_.end())
2901
 
        return (Call::CallConfiguration) 0;
2902
 
    else
2903
 
        return iter->second;
2904
 
}
2905
 
 
2906
 
bool ManagerImpl::removeCallConfig(const std::string& callID)
2907
 
{
2908
 
    return callConfigMap_.erase(callID);
 
2836
}
 
2837
 
 
2838
void ManagerImpl::setIPToIPForCall(const std::string& callID, bool IPToIP)
 
2839
{
 
2840
    if (not isIPToIP(callID)) // no IPToIP calls with the same ID
 
2841
        IPToIPMap_[callID] = IPToIP;
 
2842
}
 
2843
 
 
2844
bool ManagerImpl::isIPToIP(const std::string& callID) const
 
2845
{
 
2846
    std::map<std::string, bool>::const_iterator iter = IPToIPMap_.find(callID);
 
2847
    return iter != IPToIPMap_.end() and iter->second;
2909
2848
}
2910
2849
 
2911
2850
std::map<std::string, std::string> ManagerImpl::getCallDetails(const std::string& callID)
2934
2873
        type << call->getCallType();
2935
2874
        call_details["ACCOUNTID"] = accountid;
2936
2875
        call_details["PEER_NUMBER"] = call->getPeerNumber();
2937
 
        call_details["PEER_NAME"] = call->getPeerName();
2938
2876
        call_details["DISPLAY_NAME"] = call->getDisplayName();
2939
2877
        call_details["CALL_STATE"] = call->getStateStr();
2940
2878
        call_details["CALL_TYPE"] = type.str();
2951
2889
    return call_details;
2952
2890
}
2953
2891
 
2954
 
std::vector<std::string> ManagerImpl::getHistorySerialized() const
2955
 
{
2956
 
    return history_->get_history_serialized();
2957
 
}
2958
 
 
2959
 
void ManagerImpl::setHistorySerialized(std::vector<std::string> history)
2960
 
{
2961
 
    history_->set_serialized_history(history, preferences.getHistoryLimit());;
2962
 
    history_->save_history();
 
2892
std::vector<std::map<std::string, std::string> > ManagerImpl::getHistory() const
 
2893
{
 
2894
    return history_->getSerialized();
2963
2895
}
2964
2896
 
2965
2897
namespace {
3002
2934
std::vector<std::string> ManagerImpl::getParticipantList(const std::string& confID) const
3003
2935
{
3004
2936
    std::vector<std::string> v;
3005
 
 
3006
2937
    ConferenceMap::const_iterator iter_conf = conferenceMap_.find(confID);
3007
2938
 
3008
2939
    if (iter_conf != conferenceMap_.end()) {
3013
2944
 
3014
2945
    return v;
3015
2946
}
 
2947
 
 
2948
void ManagerImpl::saveHistory()
 
2949
{
 
2950
    if (!history_->save())
 
2951
        ERROR("Manager: could not save history!");
 
2952
}
 
2953
 
 
2954
void ManagerImpl::clearHistory()
 
2955
{
 
2956
    history_->clear();
 
2957
}