Commit 50d6c312 authored by jpbl's avatar jpbl
Browse files

we can handle incomming calls

parent 087b7e8e
......@@ -27,17 +27,25 @@
Call::Call(const std::string &sessionId,
const std::string &callId)
const std::string &callId,
bool incomming)
: mSessionId(sessionId)
, mId(callId)
, mIsIncomming(incomming)
{}
Call::Call(const Session &session,
const std::string &callId)
const std::string &callId,
bool incomming)
: mSessionId(session.id())
, mId(callId)
, mIsIncomming(incomming)
{}
bool
Call::isIncomming()
{return mIsIncomming;}
std::string
Call::call(const std::string &to)
{
......@@ -50,6 +58,7 @@ Call::call(const std::string &to)
std::string
Call::answer()
{
mIsIncomming = false;
std::list< std::string> args;
args.push_back(mId);
return Requester::instance().send(mSessionId, "answer", args);
......@@ -90,11 +99,21 @@ Call::unhold()
std::string
Call::refuse()
{
mIsIncomming = false;
std::list< std::string> args;
args.push_back(mId);
return Requester::instance().send(mSessionId, "refuse", args);
}
std::string
Call::notAvailable()
{
mIsIncomming = false;
std::list< std::string> args;
args.push_back(mId);
return Requester::instance().send(mSessionId, "notavailable", args);
}
std::string
Call::sendDtmf(char c)
{
......
......@@ -29,9 +29,17 @@ class Call
{
public:
Call(const std::string &sessionId,
const std::string &callId);
const std::string &callId,
bool incomming = false);
Call(const Session &session,
const std::string &callId);
const std::string &callId,
bool incomming = false);
/**
* This function returns true if the
* call is waiting to be picked up.
*/
bool isIncomming();
std::string id()
{return mId;}
......@@ -72,6 +80,14 @@ class Call
*/
std::string refuse();
/**
* This function will set this client to be
* not able to receive the call. It means that
* the phone can still ring. But if every client
* sent notavailable, then it will be refused.
*/
std::string notAvailable();
/**
* This function will send a tone to the line.
......@@ -91,6 +107,8 @@ class Call
* This is the unique identifier of the call.
*/
std::string mId;
bool mIsIncomming;
};
#endif
#include "globals.h"
#include "Call.hpp"
#include "Event.hpp"
#include "PhoneLineManager.hpp"
Event::Event(const std::string &code,
const std::list< std::string > &args)
: mCode(code)
, mUnusedArgs(args)
, mArgs(args)
{}
......@@ -21,21 +24,63 @@ Event::toString()
return output;
}
HangupEvent::HangupEvent(const std::string &code,
const std::list< std::string > &args)
CallRelatedEvent::CallRelatedEvent(const std::string &code,
const std::list< std::string > &args)
: Event(code, args)
{
if(args.size() != 0) {
mCallId = *args.begin();
std::list< std::string > l(getUnusedArgs());
if(l.size() != 0) {
mCallId = *l.begin();
l.pop_front();
setUnusedArgs(l);
}
}
std::string
CallRelatedEvent::getCallId()
{
return mCallId;
}
HangupEvent::HangupEvent(const std::string &code,
const std::list< std::string > &args)
: CallRelatedEvent(code, args)
{}
void
HangupEvent::execute()
{
if(mCallId.size() > 0) {
_debug("Hangup Event received for call ID: %s.\n", mCallId.c_str());
PhoneLineManager::instance().hangup(mCallId);
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());
......
......@@ -35,22 +35,50 @@ public:
virtual std::string toString();
std::list< std::string > getUnusedArgs()
{return mUnusedArgs;}
void setUnusedArgs(const std::list< std::string > &args)
{mUnusedArgs = args;}
private:
std::string mCode;
std::list< std::string > mUnusedArgs;
std::list< std::string > mArgs;
};
class CallRelatedEvent : public Event
{
public:
CallRelatedEvent(const std::string &code,
const std::list< std::string > &args);
std::string getCallId();
private:
std::string mCallId;
};
class HangupEvent : public Event
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 mCallId;
std::string mAccountId;
std::string mOrigin;
};
......
......@@ -44,7 +44,12 @@ PhoneLine::select()
mSelected = true;
if(mCall) {
mCall->unhold();
if(mCall->isIncomming()) {
mCall->answer();
}
else {
mCall->unhold();
}
}
emit selected();
......@@ -68,6 +73,18 @@ PhoneLine::unselect()
}
}
void
PhoneLine::incomming(const Call &call)
{
if(mCall) {
_debug("PhoneLine %d: Trying to set an incomming call to an active call.\n", mLine);
}
else {
mCall = new Call(call);
emit backgrounded();
}
}
void
PhoneLine::clear()
{
......@@ -138,6 +155,8 @@ PhoneLine::hangup()
mCall = NULL;
}
//This is a hack for unselect;
mSelected = true;
unselect();
}
......
......@@ -54,6 +54,8 @@ public:
void sendKey(Qt::Key c);
public slots:
void incomming(const Call &call);
/**
* Clears the buffer of the line.
*/
......
#include "PhoneLineLocker.hpp"
#include "PhoneLine.hpp"
PhoneLineLocker::PhoneLineLocker(PhoneLine *line)
PhoneLineLocker::PhoneLineLocker(PhoneLine *line, bool lock)
: mPhoneLine(line)
{
if(mPhoneLine) {
if(mPhoneLine && lock) {
mPhoneLine->lock();
}
}
......
......@@ -17,7 +17,7 @@ public:
* Retreive the "line" PhoneLine and
* locks it.
*/
PhoneLineLocker(PhoneLine *line);
PhoneLineLocker(PhoneLine *line, bool lock = true);
/**
* Unlock the currently locked PhoneLine.
......
......@@ -4,6 +4,7 @@
#include "globals.h"
#include "Call.hpp"
#include "Event.hpp"
#include "PhoneLine.hpp"
#include "PhoneLineLocker.hpp"
......@@ -14,6 +15,7 @@ PhoneLineManagerImpl::PhoneLineManagerImpl()
, mCurrentLine(NULL)
{
EventFactory::instance().registerEvent< HangupEvent >("002");
EventFactory::instance().registerEvent< IncommingEvent >("001");
mSession.getEvents();
}
......@@ -34,7 +36,7 @@ PhoneLineManagerImpl::setNbLines(unsigned int nb)
}
PhoneLine *
PhoneLineManagerImpl::selectNextAvailableLine()
PhoneLineManagerImpl::getNextAvailableLine()
{
PhoneLine *selectedLine = NULL;
......@@ -43,18 +45,29 @@ PhoneLineManagerImpl::selectNextAvailableLine()
unsigned int i = 0;
while(i < mPhoneLines.size() && !selectedLine) {
PhoneLineLocker guard(mPhoneLines[i]);
mPhoneLines[i]->lock();
if(mPhoneLines[i]->isAvailable() &&
mPhoneLines[i] != mCurrentLine) {
selectedLine = mPhoneLines[i];
}
else {
mPhoneLines[i]->unlock();
i++;
}
}
return selectedLine;
}
PhoneLine *
PhoneLineManagerImpl::selectNextAvailableLine()
{
PhoneLine *selectedLine = getNextAvailableLine();
PhoneLineLocker guard(selectedLine, false);
// If we found one available line.
if(selectedLine) {
QMutexLocker guard(&mCurrentLineMutex);
if(mCurrentLine) {
PhoneLineLocker guard(mCurrentLine);
mCurrentLine->unselect();
......@@ -66,10 +79,14 @@ PhoneLineManagerImpl::selectNextAvailableLine()
PhoneLineLocker guard(mCurrentLine);
mCurrentLine->select();
}
}
return selectedLine;
}
PhoneLine *
PhoneLineManagerImpl::getPhoneLine(unsigned int line)
{
......@@ -241,3 +258,21 @@ PhoneLineManagerImpl::clear()
}
}
void
PhoneLineManagerImpl::incomming(const std::string &,
const std::string &,
const std::string &callId)
{
PhoneLine *selectedLine = getNextAvailableLine();
PhoneLineLocker guard(selectedLine, false);
Call call(mSession, callId, true);
if(selectedLine) {
selectedLine->incomming(call);
}
else {
_debug("There's no available lines here for the incomming call ID: %s.\n",
callId.c_str());
call.notAvailable();
}
}
......@@ -82,6 +82,11 @@ public slots:
*/
void call(const QString &to);
void incomming(const std::string &accountId,
const std::string &origin,
const std::string &callId);
/**
* This function will make a call on the
* current line. If there's no selected
......@@ -103,6 +108,16 @@ public slots:
*/
void clear();
/**
* This function will return the next available line.
* The line is locked, So you'll need to unlock it.
*/
PhoneLine *getNextAvailableLine();
/**
* This function will return the next available line.
* The line is NOT locked.
*/
PhoneLine *selectNextAvailableLine();
private:
......
......@@ -17,6 +17,9 @@ SFLPhoneApp::SFLPhoneApp(int argc, char **argv)
Requester::instance().registerObject< Request >(std::string("playtone"));
Requester::instance().registerObject< Request >(std::string("playdtmf"));
Requester::instance().registerObject< EventRequest >(std::string("getevents"));
Requester::instance().registerObject< CallRelatedRequest >(std::string("answer"));
Requester::instance().registerObject< CallRelatedRequest >(std::string("notavailable"));
Requester::instance().registerObject< CallRelatedRequest >(std::string("refuse"));
Requester::instance().registerObject< CallRelatedRequest >(std::string("senddtmf"));
Requester::instance().registerObject< CallRelatedRequest >(std::string("playdtmf"));
Requester::instance().registerObject< CallRelatedRequest >(std::string("call"));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment