diff --git a/src/Makefile.am b/src/Makefile.am index 8f20fe4465ab1b29af063b16ccdb7431083848f2..1cae08ff2bb25cb7f409b7cb3b059b8e3a4b9dbc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,35 +14,12 @@ ZEROCONFLIB = ZEROCONFFLAGS = endif -sflphone_SOURCES = \ - configitem.cpp \ - configuration.cpp \ - configurationtree.cpp \ - call.cpp \ - eventthread.cpp \ - error.cpp \ - main.cpp \ - sipvoiplink.cpp \ - voIPLink.cpp \ - sipcall.cpp \ - skin.cpp \ - managerimpl.cpp \ - managerimpl.h \ - manager.h \ - global.h \ - configitem.h \ - configuration.h \ - configurationtree.h \ - eventthread.h \ - error.h \ - sipvoiplink.h \ - user_cfg.h \ - call.h \ - phonegi-bin.h \ - voIPLink.h \ - sipcall.h \ - skin.h \ - ${maintener_source} +sflphone_SOURCES = configitem.cpp configuration.cpp configurationtree.cpp \ + call.cpp eventthread.cpp error.cpp main.cpp sipvoiplink.cpp voIPLink.cpp \ + sipcall.cpp skin.cpp managerimpl.cpp managerimpl.h manager.h global.h \ + configitem.h configuration.h configurationtree.h eventthread.h error.h \ + sipvoiplink.h user_cfg.h call.h phonegi-bin.h voIPLink.h sipcall.h skin.h \ + ${maintener_source} observer.cpp @@ -54,3 +31,4 @@ sflphone_LDADD = gui/libguiframework.la audio/libaudio.la ../stund/libstun.la . KDE_CXXFLAGS = $(USE_EXCEPTIONS) AM_CPPFLAGS = $(QT_INCLUDES) $(X_INCLUDES) -I$(top_srcdir) -Igui/qt -I$(srcdir)/audio/pacpp/include $(libccext2_CFLAGS) $(libccgnu2_CFLAGS) $(portaudio_CFLAGS) +noinst_HEADERS = observer.h diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp index d8af9536dbdb221b2a7cca78f5eda368d02c2f2d..603c647ec8c3e9672d11bd7034531b8c309b0cfa 100644 --- a/src/audio/audiortp.cpp +++ b/src/audio/audiortp.cpp @@ -260,7 +260,7 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers, #else if (adu == NULL) { Manager::instance().getAudioDriver()->mainSndRingBuffer().flush(); - //Manager::instance().getAudioDriver()->stopStream(); + Manager::instance().getAudioDriver()->stopStream(); return; } #endif @@ -330,7 +330,12 @@ AudioRtpRTX::run (void) { // TODO: get frameSize from user config int frameSize = 20; // 20ms frames TimerPort::setTimer(frameSize); - + + // flush stream: + AudioLayer *audiolayer = Manager::instance().getAudioDriver(); + audiolayer->mainSndRingBuffer().flush(); + audiolayer->urgentRingBuffer().flush(); + // start running the packet queue scheduler. if (!_sym) { _sessionRecv->startRunning(); @@ -338,6 +343,8 @@ AudioRtpRTX::run (void) { } else { _session->startRunning(); } + + while (_ca->enable_audio != -1) { micVolume = Manager::instance().getMicroVolume(); @@ -361,6 +368,10 @@ AudioRtpRTX::run (void) { Thread::sleep(TimerPort::getTimer()); TimerPort::incTimer(frameSize); // 'frameSize' ms } + + audiolayer->mainSndRingBuffer().flush(); + //audiolayer->urgentRingBuffer().flush(); + audiolayer->stopStream(); delete[] data_for_speakers; delete[] data_for_speakers_tmp; diff --git a/src/audio/tonegenerator.cpp b/src/audio/tonegenerator.cpp index 79c180dd5a79e50ccf38bdcf748ed1e1c5cba26e..eb754b47da2e1ed49ee1dcf6f907d7288564c96b 100644 --- a/src/audio/tonegenerator.cpp +++ b/src/audio/tonegenerator.cpp @@ -57,7 +57,7 @@ ToneThread::run (void) { bool started = false; // How long do 'size' samples play ? - unsigned int play_time = (size * 1000) / SAMPLING_RATE; + // unsigned int play_time = (size * 1000) / SAMPLING_RATE; unsigned int pause = (size) / SAMPLING_RATE; while (Manager::instance().getZonetone()) { diff --git a/src/configitem.h b/src/configitem.h index a04d6e9e5773a32c15d0346ed15462e6ee14689d..4de9e2cbe9869188b5771e776a41f86b7ab77dd8 100644 --- a/src/configitem.h +++ b/src/configitem.h @@ -23,27 +23,25 @@ #include <string> #include <stdio.h> -using namespace std; - class ConfigItem { public: ConfigItem (void); - ConfigItem (const string& ); - ConfigItem (const string& , const string& ); + ConfigItem (const std::string& ); + ConfigItem (const std::string& , const std::string& ); ~ConfigItem (void); - string* key (void) { return _key; } - string* value (void) { return _value; } + std::string* key (void) { return _key; } + std::string* value (void) { return _value; } ConfigItem* head (void) { return _head; } void setHead (ConfigItem *h) { _head = h; } - string* getValueByKey (const string& ); - ConfigItem* getItemByKey (const string& ); - void setValue (const string& ); - void setValueByKey (const string& , const string& ); - void saveToFile (fstream*); + std::string* getValueByKey (const std::string& ); + ConfigItem* getItemByKey (const std::string& ); + void setValue (const std::string& ); + void setValueByKey (const std::string& , const std::string& ); + void saveToFile (std::fstream*); private: - string* _key; - string* _value; + std::string* _key; + std::string* _value; ConfigItem* _next; ConfigItem* _head; void init (void); diff --git a/src/configurationtree.h b/src/configurationtree.h index 81d91fdff8c9aac40ad2354d948e1cc10527744e..701f6c1f8549baf0084a806f719811df0bf139ed 100644 --- a/src/configurationtree.h +++ b/src/configurationtree.h @@ -41,14 +41,14 @@ class ConfigurationTree { public: ConfigurationTree (void); - ConfigurationTree (const string&); + ConfigurationTree (const std::string&); ~ConfigurationTree (void); ConfigSection* head (void) { return this->_head; } - int populateFromFile(const string& ); - int saveToFile (const string& ); - int setValue (const string& , const string& , int); - int setValue(const string& , const string& , const string& ); - string getValue (const string& , const string& ); + int populateFromFile(const std::string& ); + int saveToFile (const std::string& ); + int setValue (const std::string& , const std::string& , int); + int setValue(const std::string& , const std::string& , const std::string& ); + std::string getValue (const std::string& , const std::string& ); private: ConfigSection *_head; diff --git a/src/gui/guiframework.cpp b/src/gui/guiframework.cpp index e603ec3e7a92f4339489604e2c7821985aa68fb4..045e3fe201c4557004927cd605c76ff418d20024 100644 --- a/src/gui/guiframework.cpp +++ b/src/gui/guiframework.cpp @@ -23,6 +23,7 @@ using namespace std; #include "guiframework.h" #include "../manager.h" + GuiFramework::GuiFramework () {} @@ -205,3 +206,48 @@ GuiFramework::accessToDirectory (void) return 1; } +/** + * Configuration section / redirection + */ +bool +GuiFramework::getZeroconf(const std::string& sequenceId) +{ + return Manager::instance().getZeroconf(sequenceId); +} + +bool +GuiFramework::attachZeroconfEvents(const std::string& sequenceId) +{ + return Manager::instance().attachZeroconfEvents(sequenceId, *this); +} + +bool +GuiFramework::getCallStatus(const std::string& sequenceId) +{ + return Manager::instance().getCallStatus(sequenceId); +} + +bool +GuiFramework::getConfigAll(const std::string& sequenceId) +{ + return Manager::instance().getConfigAll(sequenceId); +} + +bool +GuiFramework::getConfig(const std::string& sequenceId, const std::string& name) +{ + return Manager::instance().getConfig(sequenceId, name); +} + +bool +GuiFramework::setConfig(const std::string& name, const std::string& value) +{ + return Manager::instance().setConfig(name, value); +} + +bool +GuiFramework::getConfigList(const std::string& sequenceId, const std::string& name) +{ + return Manager::instance().getConfigList(sequenceId, name); +} + diff --git a/src/gui/guiframework.h b/src/gui/guiframework.h index d44cfd08e749ffeb262dde540c1d98cb53687a25..15a6b8f497abd0a988411bd8919aec0b053988b2 100644 --- a/src/gui/guiframework.h +++ b/src/gui/guiframework.h @@ -19,13 +19,14 @@ #ifndef __GUI_FRAMEWORK_H__ #define __GUI_FRAMEWORK_H__ - /* Inherited class by GUI classes */ /* The GuiFramework class is the base of all user interface */ #include <string> +#include "server/argtokenizer.h" +#include "../observer.h" -class GuiFramework { +class GuiFramework : public Pattern::Observer { public: GuiFramework (); virtual ~GuiFramework (void); @@ -48,6 +49,13 @@ public: virtual void startVoiceMessageNotification (void) = 0; virtual void stopVoiceMessageNotification (void) = 0; + virtual void sendMessage(const std::string& code, const std::string& seqId, TokenList& arg) = 0; + virtual void sendCallMessage(const std::string& seqId, + short id, + const std::string& accountId, + const std::string& status + ) = 0; + /* Child class to parent class */ int outgoingCall (const std::string& to); int hangupCall (short id); @@ -71,10 +79,21 @@ public: bool sendDtmf (short id, char code); bool playDtmf (char code); bool playTone (); - + + // config + bool getZeroconf(const std::string& sequenceId); + bool attachZeroconfEvents(const std::string& sequenceId); + bool getCallStatus(const std::string& sequenceId); + bool getConfigAll(const std::string& sequenceId); + bool getConfig(const std::string& sequenceId, const std::string& name); + bool setConfig(const std::string& name, const std::string& value); + bool getConfigList(const std::string& sequenceId, const std::string& name); + + // Observer methods + virtual void update() {} + protected: std::string _message; - }; #endif // __GUI_FRAMEWORK_H__ diff --git a/src/gui/qt/qtGUImainwindow.h b/src/gui/qt/qtGUImainwindow.h index 4b483ccad8d65e6c37aa9fe3cf8f7abbb2708b83..ecef1f3b2f1662e352516acd3e15a59b95be3eab 100644 --- a/src/gui/qt/qtGUImainwindow.h +++ b/src/gui/qt/qtGUImainwindow.h @@ -89,13 +89,21 @@ public: virtual void peerAnsweredCall (short id); virtual int peerRingingCall (short id); virtual int peerHungupCall (short id); - virtual void displayTextMessage (short id, const string& message); - virtual void displayErrorText (short id, const string& message); - virtual void displayError (const string& error); - virtual void displayStatus (const string& status); + virtual void displayTextMessage (short id, const std::string& message); + virtual void displayErrorText (short id, const std::string& message); + virtual void displayError (const std::string& error); + virtual void displayStatus (const std::string& status); virtual void displayContext (short id); - virtual string getRingtoneFile (void); + virtual std::string getRingtoneFile (void); virtual void setup (void); + virtual void sendMessage(const std::string& code, const std::string& seqId, TokenList& arg) {} + virtual void sendCallMessage(const std::string& seqId, + short id, + const std::string& accountId, + const std::string& status + ) {} + + /* * Return the id matching to the chosen line diff --git a/src/gui/server/guiserverimpl.cpp b/src/gui/server/guiserverimpl.cpp index a584e855bfa978b074a698bdd95a6104acdbeca5..35ad1936e37009f97032d2810a91aa98201751ca 100644 --- a/src/gui/server/guiserverimpl.cpp +++ b/src/gui/server/guiserverimpl.cpp @@ -58,7 +58,7 @@ GUIServerImpl::removeSubCall(short id) { } /** - * Retreive the subcall or send 0 + * Retreive the sequenceId or send seq0 */ std::string GUIServerImpl::getSequenceIdFromId(short id) { @@ -68,6 +68,17 @@ GUIServerImpl::getSequenceIdFromId(short id) { } return "seq0"; } +/** + * Retreive the string callid from the id + */ +std::string +GUIServerImpl::getCallIdFromId(short id) { + CallMap::iterator iter = _callMap.find(id); + if (iter != _callMap.end()) { + return iter->second.callId(); + } + throw std::runtime_error("No match for this id"); +} short GUIServerImpl::getIdFromCallId(const std::string& callId) @@ -342,3 +353,34 @@ GUIServerImpl::stopVoiceMessageNotification (void) { _requestManager.sendResponse(ResponseMessage("021", "seq0", "no voice message")); } + +void +GUIServerImpl::sendMessage(const std::string& code, const std::string& seqId, TokenList& arg) +{ + _requestManager.sendResponse(ResponseMessage(code, seqId, arg)); +} + +void +GUIServerImpl::sendCallMessage(const std::string& seqId, + short id, + const std::string& accountId, + const std::string& status + ) +{ + try { + std::string callid = getCallIdFromId(id); + TokenList arg; + arg.push_back(callid); + arg.push_back(accountId); + arg.push_back(status); + _requestManager.sendResponse(ResponseMessage("100", seqId, arg)); + } catch(...) { + // no callid found + } +} + +void +GUIServerImpl::update() +{ + +} diff --git a/src/gui/server/guiserverimpl.h b/src/gui/server/guiserverimpl.h index 8ece35def10d6e27ca43f684294b70d07224047f..9f8103ad4f4e4e5e3b5c4e31db7dfc082f6158ce 100644 --- a/src/gui/server/guiserverimpl.h +++ b/src/gui/server/guiserverimpl.h @@ -41,8 +41,10 @@ public: void insertSubCall(short id, SubCall& subCall); void removeSubCall(short id); std::string getSequenceIdFromId(short id); + std::string getCallIdFromId(short id); short getIdFromCallId(const std::string& callId); + // Reimplementation of virtual functions // TODO: remove incomingCall with one parameter int incomingCall (short id); @@ -59,7 +61,14 @@ public: std::string getRingtoneFile (void); void setup (void); void startVoiceMessageNotification (void); - void stopVoiceMessageNotification (void); + void stopVoiceMessageNotification (void); + + void sendMessage(const std::string& code, const std::string& seqId, TokenList& arg); + void sendCallMessage(const std::string& seqId, + short id, + const std::string& accountId, + const std::string& status + ); bool outgoingCall (const std::string& seq, const std::string& callid, @@ -75,6 +84,9 @@ public: std::string version(); void quit() { _requestManager.quit(); } + // observer methods + void update(); + private: /** diff --git a/src/gui/server/request.cpp b/src/gui/server/request.cpp index d6ba31265bffbdb9c511534d8a81ab43dd4ab741..bf08c80669734e4705176de3842946ed52d7692e 100644 --- a/src/gui/server/request.cpp +++ b/src/gui/server/request.cpp @@ -93,7 +93,6 @@ RequestHangupAll::execute() RequestDTMF::RequestDTMF(const std::string &sequenceId, const TokenList& argList) : RequestGlobalCall(sequenceId, argList) { - TokenList::iterator iter = _argList.begin(); // check for the dtmf key diff --git a/src/gui/server/requestconfig.cpp b/src/gui/server/requestconfig.cpp index 21710662905f1bc8cbdb6623be77ce6f1c8dba4f..2de5ff377ac7c0a4997de5f96bd2c650c2bffc73 100644 --- a/src/gui/server/requestconfig.cpp +++ b/src/gui/server/requestconfig.cpp @@ -21,57 +21,125 @@ #include "guiserver.h" #include "subcall.h" - ResponseMessage RequestZeroconf::execute() { - return message("500","TODO"); -} - -ResponseMessage -Request::execute() -{ - return message("500","TODO"); + if (GUIServer::instance().getZeroconf(_sequenceId)) { + return message("200", "OK"); + } else { + return message("501","Zeroconf not enabled or activated"); + } } ResponseMessage RequestZeroconfEvent::execute() { - return message("500","TODO"); + if (GUIServer::instance().attachZeroconfEvents(_sequenceId)) { + return message("200", "OK"); + } else { + return message("501","Zeroconf not enabled or activated"); + } } ResponseMessage RequestCallStatus::execute() { - return message("500","TODO"); + if (GUIServer::instance().getCallStatus(_sequenceId)) { + return message("200", "OK"); + } else { + return message("500","Server Error"); + } } ResponseMessage RequestConfigGetAll::execute() { - return message("500","TODO"); + if (GUIServer::instance().getConfigAll(_sequenceId)) { + return message("200", "OK"); + } else { + return message("500","Server Error"); + } +} + +RequestConfigGet::RequestConfigGet(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) +{ + TokenList::iterator iter = _argList.begin(); + if (iter != _argList.end()) { + _name = *iter; + _argList.pop_front(); + } else { + throw RequestConstructorException(); + } } ResponseMessage RequestConfigGet::execute() { - return message("500","TODO"); + if (GUIServer::instance().getConfig(_sequenceId, _name)) { + return message("200", "OK"); + } else { + return message("500","Server Error"); + } +} + +RequestConfigSet::RequestConfigSet(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) +{ + TokenList::iterator iter = _argList.begin(); + + // get two strings arguments + bool argsAreValid = false; + if (iter != _argList.end()) { + _name = *iter; + _argList.pop_front(); + iter++; + if (iter != _argList.end()) { + _value = *iter; + _argList.pop_front(); + argsAreValid = true; + } + } + if (!argsAreValid) { + throw RequestConstructorException(); + } } ResponseMessage RequestConfigSet::execute() { - return message("500","TODO"); + if (GUIServer::instance().setConfig(_name, _value)) { + return message("200", "OK"); + } else { + return message("500","Server Error"); + } } ResponseMessage RequestConfigSave::execute() { - return message("500","TODO"); + if (GUIServer::instance().saveConfig()) { + return message("200", "Config saved"); + } else { + return message("400","Error Unable to save the configuration"); + } +} + +RequestList::RequestList(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) +{ + TokenList::iterator iter = _argList.begin(); + if (iter != _argList.end()) { + _name = *iter; + _argList.pop_front(); + } else { + throw RequestConstructorException(); + } } ResponseMessage RequestList::execute() { - return message("500","TODO"); + if (GUIServer::instance().getConfigList(_sequenceId, _name)) { + return message("200", "OK"); + } else { + return message("500","Server Error"); + } } diff --git a/src/gui/server/requestconfig.h b/src/gui/server/requestconfig.h index f15e2f5b8b9f927d87a548bd493cfac031257c60..69b0495802a0d91434fcb6623b35f47a50cddb03 100644 --- a/src/gui/server/requestconfig.h +++ b/src/gui/server/requestconfig.h @@ -53,15 +53,20 @@ public: class RequestConfigGet : public RequestGlobal { public: - RequestConfigGet(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + RequestConfigGet(const std::string &sequenceId, const TokenList& argList); ResponseMessage execute(); +private: + std::string _name; }; class RequestConfigSet : public RequestGlobal { public: - RequestConfigSet(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + RequestConfigSet(const std::string &sequenceId, const TokenList& argList); ResponseMessage execute(); +private: + std::string _name; + std::string _value; }; @@ -73,8 +78,10 @@ public: class RequestList : public RequestGlobal { public: - RequestList(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) {} + RequestList(const std::string &sequenceId, const TokenList& argList); ResponseMessage execute(); +private: + std::string _name; }; #endif // __REQUESTCONFIG_H__ diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index f7bd78090c65e50138040175656029888b2a3bc6..0e9ba08342d053d7668738cc739c74cb32b9cce1 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -53,6 +53,7 @@ #ifdef USE_ZEROCONF #include "zeroconf/DNSService.h" +#include "zeroconf/DNSServiceTXTRecord.h" #endif using namespace std; @@ -1060,4 +1061,102 @@ ManagerImpl::initVolume() setMicroVolume(get_config_fields_int(AUDIO, VOLUME_MICRO)); } +// configuration function requests +bool +ManagerImpl::getZeroconf(const std::string& sequenceId) +{ + bool returnValue = false; +#ifdef USE_ZEROCONF + if (_useZeroconf && _gui != NULL) { + TokenList arg; + TokenList argTXT; + std::string newService = "new service"; + std::string newTXT = "new txt record"; + DNSServiceMap services = _DNSService->getServices(); + DNSServiceMap::iterator iter = services.begin(); + arg.push_back(newService); + while(iter!=services.end()) { + arg.push_first(iter->first); + _gui.sendMessage("100",sequenceId,arg); + arg.pop_first(); // remove the first, the name + + TXTRecordMap record = iter->second.getTXTRecords(); + TXTRecordMap::iterator iterTXT = record.begin(); + while(iterTXT!=record.end()) { + argTXT.flush(); + argTXT.push_back(iter->first); + argTXT.push_back(iterTXT->first); + argTXT.push_back(iterTXT->second); + argTXT.push_back(newTXT); + _gui.sendMessage("101",sequenceId,arg); + iterTXT++; + } + iter++; + } + returnValue = true; + } +#endif + return returnValue; +} + +bool +ManagerImpl::attachZeroconfEvents(const std::string& sequenceId, const Pattern::Observer &observer) +{ + bool returnValue = false; + // don't need the _gui like getZeroconf function + // because Observer is here +#ifdef USE_ZEROCONF + if (_useZeroconf) { + _DNSService->attach(sequenceId,observer); + returnValue = true; + } +#endif + return returnValue; +} + +bool +ManagerImpl::getCallStatus(const std::string& sequenceId) +{ + bool returnValue = false; + // TODO: implement account + std::string accountId = "acc1"; + if (_gui!=NULL) { + CallVector::iterator iter = _callVector.begin(); + while(iter!=_callVector.end()){ + _gui->sendCallMessage(sequenceId, (*iter)->getId(), accountId, (*iter)->getStatus()); + iter++; + } + returnValue = true; + } + return returnValue; +} + +bool +ManagerImpl::getConfigAll(const std::string& sequenceId) +{ + bool returnValue = false; + return returnValue; +} + +bool +ManagerImpl::getConfig(const std::string& sequenceId, const std::string& name) +{ + bool returnValue = false; + return returnValue; +} + +bool +ManagerImpl::setConfig(const std::string& name, const std::string& value) +{ + bool returnValue = false; + return returnValue; +} + +bool +ManagerImpl::getConfigList(const std::string& sequenceId, const std::string& name) +{ + bool returnValue = false; + return returnValue; +} + // EOF diff --git a/src/managerimpl.h b/src/managerimpl.h index 6da774357fc3248e01c617c8bb82b644ba389ef6..07b7b7d1c002fdc5457acd417b550effc593f2fd 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -27,6 +27,7 @@ #include "../stund/stun.h" #include "call.h" #include "audio/audiodevice.h" +#include "observer.h" class AudioLayer; class CodecDescriptor; @@ -73,6 +74,11 @@ struct device_t{ const char* deviceName; }; +/** + * To send multiple string + */ +typedef std::list<std::string> TokenList; + class ManagerImpl { public: ManagerImpl (void); @@ -185,7 +191,17 @@ public: // bool isCurrentId (short id); void startVoiceMessageNotification (void); void stopVoiceMessageNotification (void); - + + // configuration function requests + bool getZeroconf(const std::string& sequenceId); + bool attachZeroconfEvents(const std::string& sequenceId, const Pattern::Observer &observer); + bool getCallStatus(const std::string& sequenceId); + bool getConfigAll(const std::string& sequenceId); + bool getConfig(const std::string& sequenceId, const std::string& name); + bool setConfig(const std::string& name, const std::string& value); + bool getConfigList(const std::string& sequenceId, const std::string& name); + + /* * Handle audio sounds heard by a caller while they wait for their * connection to a called party to be completed. diff --git a/src/observer.cpp b/src/observer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..717a4ca2f5a9c5a179fd8102249a8e37c2116cf7 --- /dev/null +++ b/src/observer.cpp @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2005 Savoir-Faire Linux inc. + * Author: Yan Morin <yan.morin@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. + */ + +#include "observer.h" +#include <algorithm> +namespace Pattern { + +void +Subject::attach(Observer& observer) +{ + if (std::find(_observers.begin(), _observers.end(), &observer) == _observers.end()) { + _observers.push_back(&observer); + } +} + +void +Subject::detach(Observer& observer) +{ + std::list<Observer*>::iterator iter = std::find(_observers.begin(), _observers.end(), &observer); + if ( iter != _observers.end()) { + _observers.erase(iter); + } +} + +void +Subject::notify() +{ + std::list<Observer*>::iterator iter = _observers.begin(); + while( iter != _observers.end()) { + (*iter)->update(); + iter++; + } +} + +} // end of namespace diff --git a/src/observer.h b/src/observer.h new file mode 100644 index 0000000000000000000000000000000000000000..785cba8741a1e4ad6d1c9dbf44c48882ee46cd36 --- /dev/null +++ b/src/observer.h @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2005 Savoir-Faire Linux inc. + * Author: Yan Morin <yan.morin@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 __PATTERN_OBSERVER_H_ +#define __PATTERN_OBSERVER_H_ + +#include <list> + +/** + * Observer design pattern interface + */ +namespace Pattern { + +class Observer { +public: + virtual ~Observer() {}; + virtual void update() = 0; +}; + +class Subject { +public: + virtual ~Subject() {}; + void attach(Observer& observer); + void detach(Observer& observer); + void notify(); + +private: + std::list<Observer*> _observers; +}; + +} // end namespace + +#endif // __PATTERN_OBSERVER_H_ diff --git a/src/zeroconf/DNSService.cpp b/src/zeroconf/DNSService.cpp index c4e4ab2cfc1819619e9067493ab66176315550a9..b5b5a80d45a9776b8688ed6baeae0c5a44e1297b 100644 --- a/src/zeroconf/DNSService.cpp +++ b/src/zeroconf/DNSService.cpp @@ -90,9 +90,8 @@ void DNSService::addService(const std::string &service) */ void DNSService::removeService(const std::string &service) { - _mutex.enterMutex(); + ost::MutexLock(_mutex); _services.erase(service); - _mutex.leaveMutex(); } /** @@ -111,6 +110,17 @@ DNSService::listServices() } } +/** + * Return every services + */ +DNSServiceMap +DNSService::getServices() +{ + ost::MutexLock(_mutex); + return _services; +} + + /** * Query a service and wait for the anwser * the queryCallback will show the result diff --git a/src/zeroconf/DNSService.h b/src/zeroconf/DNSService.h index f832eb849160928cdafb371b495bf04eb8fdec97..cd6b2f0bd85c8282461b834830a7289a37336efa 100644 --- a/src/zeroconf/DNSService.h +++ b/src/zeroconf/DNSService.h @@ -26,12 +26,13 @@ #include <dns_sd.h> #include <cc++/thread.h> +#include "../observer.h" class DNSQueryThread; class DNSServiceTXTRecord; typedef std::map<std::string, DNSServiceTXTRecord> DNSServiceMap; -class DNSService +class DNSService : public Pattern::Subject { public: DNSService(); @@ -41,6 +42,7 @@ public: void addService(const std::string &service); // adding every services void removeService(const std::string &service); // remove a service void listServices(); // listing services (call addService before) + DNSServiceMap getServices(); // get all DNS Service void stop(); // after the browsing loop stop void queryService(const std::string &service); // query the TXT record of a service diff --git a/src/zeroconf/DNSServiceTXTRecord.h b/src/zeroconf/DNSServiceTXTRecord.h index 6cddb22e829ca1d9ba38723abec25c3f3f87c1a2..907fee3ced76de6b5941dbe2dd9b4144620cd4ed 100644 --- a/src/zeroconf/DNSServiceTXTRecord.h +++ b/src/zeroconf/DNSServiceTXTRecord.h @@ -35,6 +35,7 @@ public: inline void clear(void) { _map.clear(); }; inline int size(void) { return _map.size(); }; void listValue(); + TXTRecordMap getTXTRecords() { return _map; } private: TXTRecordMap _map;