Commit 8cc05a3b authored by jpbl's avatar jpbl

we can get the status now.

parent 1480d1d0
......@@ -41,7 +41,7 @@ class Call
*/
bool isIncomming();
std::string id()
std::string id() const
{return mId;}
std::string call(const std::string &to);
......
#include "globals.h"
#include "CallStatus.hpp"
#include "PhoneLineManager.hpp"
CallStatus::CallStatus(const std::string &code,
const std::list< std::string > &args)
: CallRelatedEvent(code, args)
{
std::list< std::string > l = getUnusedArgs();
if(l.size() >= 3) {
mAccountId = *l.begin();
l.pop_front();
mDestination = *l.begin();
l.pop_front();
mStatus = *l.begin();
l.pop_front();
setUnusedArgs(l);
}
}
void
CallStatus::execute()
{
std::string id = getCallId();
if(id.size() > 0) {
_debug("%s status received for call ID: %s.\n",
mStatus.c_str(),
id.c_str());
PhoneLineManager::instance().addCall(mAccountId, getCallId(), mDestination, mStatus);
}
else {
_debug("Status invalid: %s\n", toString().c_str());
}
}
/**
* Copyright (C) 2004-2005 Savoir-Faire Linux inc.
* Author: Jean-Philippe Barrette-LaPierre
* <jean-philippe.barrette-lapierre@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __CALLSTATUS_HPP__
#define __CALLSTATUS_HPP__
#include "Event.hpp"
class CallStatus : public CallRelatedEvent
{
public:
CallStatus(const std::string &code,
const std::list< std::string > &args);
void execute();
protected:
std::string mAccountId;
std::string mDestination;
std::string mStatus;
};
#endif
/**
* Copyright (C) 2004-2005 Savoir-Faire Linux inc.
* Author: Jean-Philippe Barrette-LaPierre
* <jean-philippe.barrette-lapierre@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __CALLSTATUSFACTORY_HPP__
#define __CALLSTATUSFACTORY_HPP__
#include "EventFactory.hpp"
typedef utilspp::SingletonHolder< EventFactoryImpl< Event > > CallStatusFactory;
#endif
......@@ -2,7 +2,6 @@
#include "Call.hpp"
#include "Event.hpp"
#include "PhoneLineManager.hpp"
Event::Event(const std::string &code,
const std::list< std::string > &args)
......@@ -15,7 +14,7 @@ Event::Event(const std::string &code,
void
Event::execute()
{
_debug("Received: %s.\n", toString().c_str());
_debug("Received: %s\n", toString().c_str());
}
std::string
......@@ -48,48 +47,3 @@ CallRelatedEvent::getCallId()
{
return mCallId;
}
HangupEvent::HangupEvent(const std::string &code,
const std::list< std::string > &args)
: CallRelatedEvent(code, args)
{}
void
HangupEvent::execute()
{
std::string id = getCallId();
if(id.size() > 0) {
_debug("Hangup Event received for call ID: %s.\n", id.c_str());
PhoneLineManager::instance().hangup(id);
}
else {
_debug("Hangup Event invalid (missing call ID): %s\n", toString().c_str());
}
}
IncommingEvent::IncommingEvent(const std::string &code,
const std::list< std::string > &args)
: CallRelatedEvent(code, args)
{
std::list< std::string > l;
if(getUnusedArgs().size() >= 3) {
mAccountId = *l.begin();
l.pop_front();
mOrigin = *l.begin();
l.pop_front();
setUnusedArgs(l);
}
}
void
IncommingEvent::execute()
{
std::string id = getCallId();
if(id.size() > 0) {
_debug("Hangup Event received for call ID: %s.\n", id.c_str());
PhoneLineManager::instance().incomming(mAccountId, mOrigin, getCallId());
}
else {
_debug("Event invalid: %s\n", toString().c_str());
}
}
......@@ -59,27 +59,5 @@ private:
std::string mCallId;
};
class HangupEvent : public CallRelatedEvent
{
public:
HangupEvent(const std::string &code,
const std::list< std::string > &args);
virtual void execute();
};
class IncommingEvent : public CallRelatedEvent
{
public:
IncommingEvent(const std::string &code,
const std::list< std::string > &args);
virtual void execute();
private:
std::string mAccountId;
std::string mOrigin;
};
#endif
......@@ -37,18 +37,20 @@ PhoneLine::unlock()
}
void
PhoneLine::select()
PhoneLine::select(bool hardselect)
{
if(!mSelected) {
_debug("PhoneLine %d: I am selected.\n", mLine);
mSelected = true;
if(mCall) {
if(mCall->isIncomming()) {
mCall->answer();
}
else {
mCall->unhold();
if(!hardselect) {
if(mCall) {
if(mCall->isIncomming()) {
mCall->answer();
}
else {
mCall->unhold();
}
}
}
......@@ -56,14 +58,29 @@ PhoneLine::select()
}
}
void
PhoneLine::disconnect()
{
mSelected = false;
_debug("PhoneLine %d: I am disconnected.\n", mLine);
if(mCall) {
delete mCall;
mCall = NULL;
}
emit unselected();
}
void
PhoneLine::unselect()
PhoneLine::unselect(bool hardselect)
{
if(mSelected) {
_debug("PhoneLine %d: I am unselected.\n", mLine);
mSelected = false;
if(mCall) {
mCall->hold();
if(!hardselect) {
mCall->hold();
}
emit backgrounded();
}
else {
......@@ -77,7 +94,7 @@ void
PhoneLine::incomming(const Call &call)
{
if(mCall) {
_debug("PhoneLine %d: Trying to set an incomming call to an active call.\n", mLine);
_debug("PhoneLine %d: Trying to set a phone line to an active call.\n", mLine);
}
else {
mCall = new Call(call);
......@@ -173,3 +190,4 @@ PhoneLine::getCallId()
return id;
}
......@@ -64,12 +64,21 @@ public slots:
/**
* The user selected this line.
*/
void select();
void select(bool hardselect = false);
/**
* This phoneline is no longer selected.
*/
void unselect();
void unselect(bool hardselect = false);
/**
* This will do a hard unselect. it means it
* will remove the call if there's one.
*/
void disconnect();
void setState(const std::string &){}
void setPeer(const std::string &){}
signals:
......
......@@ -4,8 +4,9 @@
#include "globals.h"
#include "Call.hpp"
#include "Event.hpp"
#include "CallStatusFactory.hpp"
#include "SFLEvents.hpp"
#include "SFLCallStatus.hpp"
#include "PhoneLine.hpp"
#include "PhoneLineLocker.hpp"
#include "PhoneLineManager.hpp"
......@@ -16,9 +17,22 @@ PhoneLineManagerImpl::PhoneLineManagerImpl()
, mCurrentLine(NULL)
, mIsInitialized(false)
{
EventFactory::instance().registerEvent< HangupEvent >("002");
EventFactory::instance().registerEvent< IncommingEvent >("001");
EventFactory::instance().registerEvent< HangupEvent >("002");
EventFactory::instance().registerEvent< TryingStatus >("110");
EventFactory::instance().registerEvent< RingingStatus >("111");
EventFactory::instance().registerEvent< HoldStatus >("112");
EventFactory::instance().registerEvent< EstablishedStatus >("113");
EventFactory::instance().registerEvent< BusyStatus >("114");
EventFactory::instance().registerEvent< CongestionStatus >("115");
EventFactory::instance().registerEvent< WrongNumberStatus >("116");
QObject::connect(this, SIGNAL(disconnected()),
this, SLOT(closeSession()));
QObject::connect(this, SIGNAL(readyToHandleEvents),
this, SLOT(handleEvents()));
QObject::connect(this, SIGNAL(connected()),
this, SIGNAL(readyToSendStatus()));
QObject::connect(this, SIGNAL(readyToSendStatus()),
this, SLOT(startSession()));
}
......@@ -72,10 +86,37 @@ PhoneLineManagerImpl::startSession()
{
isInitialized();
mSession->getCallStatus();
}
void
PhoneLineManagerImpl::handleEvents()
{
isInitialized();
mSession->getEvents();
}
void
PhoneLineManagerImpl::closeSession()
{
isInitialized();
QMutexLocker guard(&mPhoneLinesMutex);
mCurrentLineMutex.lock();
mCurrentLine = NULL;
mCurrentLineMutex.unlock();
unsigned int i = 0;
while(i < mPhoneLines.size()) {
PhoneLineLocker guard(mPhoneLines[i]);
mPhoneLines[i]->disconnect();
i++;
}
}
PhoneLine *
PhoneLineManagerImpl::getCurrentLine()
{
......@@ -90,6 +131,7 @@ PhoneLineManagerImpl::setNbLines(unsigned int nb)
{
isInitialized();
QMutexLocker guard(&mPhoneLinesMutex);
mPhoneLines.clear();
for(unsigned int i = 0; i < nb; i++) {
mPhoneLines.push_back(new PhoneLine(*mSession, i + 1));
......@@ -209,12 +251,39 @@ PhoneLineManagerImpl::sendKey(Qt::Key c)
}
void
PhoneLineManagerImpl::selectLine(const std::string &callId, bool hardselect)
{
isInitialized();
PhoneLine *selectedLine = NULL;
mPhoneLinesMutex.lock();
unsigned int line = 0;
while(!selectedLine && line < mPhoneLines.size()) {
if(mPhoneLines[line]->getCallId() == callId) {
selectedLine = mPhoneLines[line];
}
else {
line++;
}
}
mPhoneLinesMutex.unlock();
if(selectedLine) {
selectLine(line, hardselect);
}
else {
_debug("PhoneLineManager: Tried to selected line with call ID (%s), "
"which appears to be invalid.\n", callId.c_str());
}
}
/**
* Warning: This function might 'cause a problem if
* we select 2 line in a very short time.
*/
void
PhoneLineManagerImpl::selectLine(unsigned int line)
PhoneLineManagerImpl::selectLine(unsigned int line, bool hardselect)
{
isInitialized();
......@@ -237,18 +306,18 @@ PhoneLineManagerImpl::selectLine(unsigned int line)
if(oldLine != selectedLine) {
if(oldLine != NULL) {
PhoneLineLocker guard(oldLine);
oldLine->unselect();
oldLine->unselect(hardselect);
}
PhoneLineLocker guard(selectedLine);
selectedLine->select();
selectedLine->select(hardselect);
if(selectedLine->isAvailable()) {
mSession->playTone();
}
}
}
else {
_debug("Tried to selected line %d, which appears to be invalid.\n", line);
_debug("PhoneLineManager: Tried to selected line %d, which appears to be invalid.\n", line);
}
}
......@@ -336,19 +405,38 @@ PhoneLineManagerImpl::clear()
void
PhoneLineManagerImpl::incomming(const std::string &,
const std::string &,
const std::string &peer,
const std::string &callId)
{
Call call(*mSession, callId, true);
addCall(call, peer, "Incomming");
}
void
PhoneLineManagerImpl::addCall(const std::string &,
const std::string &callId,
const std::string &peer,
const std::string &state)
{
addCall(Call(*mSession, callId), peer, state);
}
void
PhoneLineManagerImpl::addCall(Call call,
const std::string &peer,
const std::string &state)
{
PhoneLine *selectedLine = getNextAvailableLine();
PhoneLineLocker guard(selectedLine, false);
Call call(*mSession, callId, true);
if(selectedLine) {
selectedLine->incomming(call);
selectedLine->setPeer(peer);
selectedLine->setState(state);
}
else {
_debug("There's no available lines here for the incomming call ID: %s.\n",
callId.c_str());
_debug("PhoneLineManager: There's no available lines here for the incomming call ID: %s.\n",
call.id().c_str());
call.notAvailable();
}
}
......@@ -10,6 +10,7 @@
class PhoneLine;
#include "Account.hpp"
#include "Call.hpp"
#include "EventFactory.hpp"
#include "Session.hpp"
......@@ -46,6 +47,9 @@ signals:
void selected(unsigned int);
void connected();
void disconnected();
void readyToSendStatus();
void readyToHandleEvents();
void gotErrorOnCallStatus();
public slots:
/**
......@@ -106,10 +110,25 @@ public slots:
*/
void call(const QString &to);
/**
* This function will add an incomming call
* on a phone line.
*/
void incomming(const std::string &accountId,
const std::string &origin,
const std::string &callId);
const std::string &callId,
const std::string &peer);
/**
* This function is used to add a call on a
* phone line.
*/
void addCall(Call call,
const std::string &peer,
const std::string &state);
void addCall(const std::string &accountId,
const std::string &callId,
const std::string &peer,
const std::string &state);
/**
* This function will make a call on the
......@@ -124,7 +143,16 @@ public slots:
* This function will switch the lines. If the line
* is invalid, it just do nothing.
*/
void selectLine(unsigned int line);
void selectLine(unsigned int line,
bool hardselect = false);
/**
* This function will switch the line to the line having
* the given call id. If the line is invalid, it just do
* nothing.
*/
void selectLine(const std::string &callId,
bool hardselect = false);
/**
* This function will clear the buffer of the active
......@@ -144,6 +172,18 @@ public slots:
*/
PhoneLine *selectNextAvailableLine();
/**
* This function will send the getevents request
* to the server.
*
* NOTE: This function MUST be called AFTER getcallstatus's
* completion.
*/
void handleEvents();
void errorOnCallStatus()
{emit gotErrorOnCallStatus();}
private slots:
/**
* This will send all the command needed when a
......@@ -151,6 +191,13 @@ public slots:
*/
void startSession();
/**
* This function is called when we are disconnected
* from the server. This will unselect all phone lines.
*/
void closeSession();
private:
void isInitialized();
......
......@@ -32,6 +32,20 @@ Request::Request(const std::string &sequenceId,
, mArgs(args)
{}
std::list< std::string >
Request::parseArgs(const std::string &message)
{
std::istringstream stream(message);
std::string s;
std::list< std::string > args;
while(stream.good()) {
stream >> s;
args.push_back(s);
}
return args;
}
void
Request::onError(const std::string &code, const std::string &message)
{
......
......@@ -37,6 +37,12 @@ class Request
virtual ~Request(){}
/**