diff --git a/daemon/src/account.h b/daemon/src/account.h index 349c3ec89d4d796d6d7054a969295f43edeaf38d..1c46c08be03088dab24dc492b8c1b10dbad15335 100644 --- a/daemon/src/account.h +++ b/daemon/src/account.h @@ -156,18 +156,6 @@ class Account : public Serializable { */ virtual ~Account(); - /** - * Method called by the configuration engine to serialize instance's information - * into configuration file. - */ - virtual void serialize(Conf::YamlEmitter *emitter) = 0; - - /** - * Method called by the configuration engine to restore instance internal state - * from configuration file. - */ - virtual void unserialize(Conf::MappingNode *map) = 0; - virtual void setAccountDetails(std::map<std::string, std::string> details) = 0; virtual std::map<std::string, std::string> getAccountDetails() const = 0; diff --git a/daemon/src/audio/audiorecord.cpp b/daemon/src/audio/audiorecord.cpp index 5b0d36d1543c1b2c1826f703cc56fc1b04f825e0..a8215080c434cb25b9a1f14f55285f6094eea677 100644 --- a/daemon/src/audio/audiorecord.cpp +++ b/daemon/src/audio/audiorecord.cpp @@ -245,6 +245,27 @@ bool AudioRecord::setRawFile() return true; } +namespace { + std::string header_to_string(const wavhdr &hdr) + { + std::stringstream ss; + ss << hdr.riff << "\0 " + << hdr.file_size << " " + << hdr.wave << "\0 " + << hdr.fmt << "\0 " + << hdr.chunk_size << " " + << hdr.format_tag << " " + << hdr.num_chans << " " + << hdr.sample_rate << " " + << hdr.bytes_per_sec << " " + << hdr.bytes_per_samp << " " + << hdr.bits_per_samp << " " + << hdr.data << "\0 " + << hdr.data_length; + return ss.str(); + } +} + bool AudioRecord::setWavFile() { DEBUG("AudioRecord: Create new wave file %s, sampling rate: %d", savePath_.c_str(), sndSmplRate_); @@ -256,34 +277,32 @@ bool AudioRecord::setWavFile() return false; } - struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1, - sndSmplRate_, 0, 2, 16, "dat", 0 - }; - - hdr.riff[3] = 'F'; - - hdr.wave[3] = 'E'; - - hdr.fmt[3] = ' '; - - hdr.data[3] = 'a'; - - hdr.num_chans = channels_; - - hdr.bits_per_samp = 16; - - hdr.bytes_per_samp = (SINT16)(channels_ * hdr.bits_per_samp / 8); - - hdr.bytes_per_sec = (SINT32)(hdr.sample_rate * hdr.bytes_per_samp); - + /* The text fields are NOT supposed to be null terminated, so we have to + * write them as arrays since strings enclosed in quotes include a + * null character */ + wavhdr hdr = {{'R', 'I', 'F', 'F'}, + 44, + {'W', 'A', 'V', 'E'}, + {'f','m', 't', ' '}, + 16, + 1, + channels_, + sndSmplRate_, + -1, /* initialized below */ + -1, /* initialized below */ + 16, + {'d', 'a', 't', 'a'}, + 0}; + + hdr.bytes_per_samp = channels_ * hdr.bits_per_samp / 8; + hdr.bytes_per_sec = hdr.sample_rate * hdr.bytes_per_samp; if (fwrite(&hdr, 4, 11, fileHandle_) != 11) { WARN("AudioRecord: Error: could not write WAV header for file. "); return false; } - DEBUG("AudioRecord: created WAV file successfully."); - + DEBUG("AudioRecord: Wrote wave header \"%s\"", header_to_string(hdr).c_str()); return true; } diff --git a/daemon/src/config/serializable.h b/daemon/src/config/serializable.h index 26684f85f3104adc3ca3cd3de723c848c8fcff4a..0299f8e5e09cd47865b735062efab6352182a235 100644 --- a/daemon/src/config/serializable.h +++ b/daemon/src/config/serializable.h @@ -31,18 +31,17 @@ #ifndef __SERIALIZABLE_H__ #define __SERIALIZABLE_H__ - -#include "yamlparser.h" -#include "yamlemitter.h" -#include "yamlnode.h" +namespace Conf { + class YamlEmitter; + class MappingNode; +} class Serializable { public: virtual ~Serializable() {}; virtual void serialize(Conf::YamlEmitter *emitter) = 0; - - virtual void unserialize(Conf::MappingNode *map) = 0; + virtual void unserialize(const Conf::MappingNode *map) = 0; }; #endif diff --git a/daemon/src/config/yamlnode.cpp b/daemon/src/config/yamlnode.cpp index a02808f1b1d3135ab8406ac0c17b7b538dfa336b..16951e028037ec1d45d1b8b1b897c1614f58b191 100644 --- a/daemon/src/config/yamlnode.cpp +++ b/daemon/src/config/yamlnode.cpp @@ -108,10 +108,9 @@ void MappingNode::removeKeyValue(const std::string &key) } -YamlNode *MappingNode::getValue(const std::string &key) +YamlNode *MappingNode::getValue(const std::string &key) const { - - Mapping::iterator it = map.find(key); + Mapping::const_iterator it = map.find(key); if (it != map.end()) { return it->second; @@ -121,7 +120,7 @@ YamlNode *MappingNode::getValue(const std::string &key) } } -void MappingNode::getValue(const std::string &key, bool *b) +void MappingNode::getValue(const std::string &key, bool *b) const { ScalarNode *node = static_cast<ScalarNode*>(getValue(key)); @@ -132,7 +131,7 @@ void MappingNode::getValue(const std::string &key, bool *b) *b = v == "true"; } -void MappingNode::getValue(const std::string &key, int *i) +void MappingNode::getValue(const std::string &key, int *i) const { ScalarNode *node = static_cast<ScalarNode*>(getValue(key)); if (!node) @@ -141,7 +140,7 @@ void MappingNode::getValue(const std::string &key, int *i) *i = atoi(node->getValue().c_str()); } -void MappingNode::getValue(const std::string &key, std::string *v) +void MappingNode::getValue(const std::string &key, std::string *v) const { ScalarNode *node = static_cast<ScalarNode*>(getValue(key)); diff --git a/daemon/src/config/yamlnode.h b/daemon/src/config/yamlnode.h index 1cd9d9e6777252fc9a19deff5b233999f68ef574..5ca28b13111a44a96479876b3482f2c3c2559ed0 100644 --- a/daemon/src/config/yamlnode.h +++ b/daemon/src/config/yamlnode.h @@ -48,8 +48,7 @@ enum NodeType { DOCUMENT, SCALAR, MAPPING, SEQUENCE }; class YamlNode { public: - - YamlNode(NodeType t, YamlNode *top=NULL) : type(t), topNode(top) {} + YamlNode(NodeType t, YamlNode *top = NULL) : type(t), topNode(top) {} virtual ~YamlNode() {} @@ -123,10 +122,10 @@ class MappingNode : public YamlNode { void removeKeyValue(const std::string &key); - YamlNode *getValue(const std::string &key); - void getValue(const std::string &key, bool *b); - void getValue(const std::string &key, int *i); - void getValue(const std::string &key, std::string *s); + YamlNode *getValue(const std::string &key) const; + void getValue(const std::string &key, bool *b) const; + void getValue(const std::string &key, int *i) const; + void getValue(const std::string &key, std::string *s) const; virtual void deleteChildNodes(); diff --git a/daemon/src/iax/iaxaccount.cpp b/daemon/src/iax/iaxaccount.cpp index 4e975ce5e840ff571c7c73cd949f087f9d87d87f..98d9c7fcb4a7d11bbc714edf1f774dc8af308c23 100644 --- a/daemon/src/iax/iaxaccount.cpp +++ b/daemon/src/iax/iaxaccount.cpp @@ -36,6 +36,8 @@ #include "iaxaccount.h" #include "iaxvoiplink.h" #include "manager.h" +#include "config/yamlnode.h" +#include "config/yamlemitter.h" IAXAccount::IAXAccount(const std::string& accountID) : Account(accountID, "iax2"), password_(), @@ -88,7 +90,7 @@ void IAXAccount::serialize(Conf::YamlEmitter *emitter) } } -void IAXAccount::unserialize(Conf::MappingNode *map) +void IAXAccount::unserialize(const Conf::MappingNode *map) { if (map == NULL) { ERROR("IAXAccount: Error: Map is NULL in unserialize"); diff --git a/daemon/src/iax/iaxaccount.h b/daemon/src/iax/iaxaccount.h index 7df121d90c36d5f0251546aa6819ff8e632ec51b..32a9c20aed30cba5f54192e6c6e5b509fbcb2731 100644 --- a/daemon/src/iax/iaxaccount.h +++ b/daemon/src/iax/iaxaccount.h @@ -46,8 +46,7 @@ class IAXAccount : public Account { ~IAXAccount(); virtual void serialize(Conf::YamlEmitter *emitter); - - virtual void unserialize(Conf::MappingNode *map); + virtual void unserialize(const Conf::MappingNode *map); void setAccountDetails(std::map<std::string, std::string> details); diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp index 610984b0c2d991b73386f75100294f2a88f56623..1b4cf25c763e137dadb57c4832c2ad661cff0014 100644 --- a/daemon/src/iax/iaxvoiplink.cpp +++ b/daemon/src/iax/iaxvoiplink.cpp @@ -396,8 +396,7 @@ IAXVoIPLink::carryingDTMFdigits(const std::string& id, char code) } void -IAXVoIPLink::sendTextMessage(sfl::InstantMessaging &module, - const std::string& callID, +IAXVoIPLink::sendTextMessage(const std::string& callID, const std::string& message, const std::string& /*from*/) { @@ -405,11 +404,10 @@ IAXVoIPLink::sendTextMessage(sfl::InstantMessaging &module, if (call) { ost::MutexLock lock(mutexIAX_); - module.send_iax_message(call->session, callID, message.c_str()); + sfl::InstantMessaging::send_iax_message(call->session, callID, message.c_str()); } } - std::string IAXVoIPLink::getCurrentCodecName(Call *c) const { @@ -418,7 +416,6 @@ IAXVoIPLink::getCurrentCodecName(Call *c) const return audioCodec ? audioCodec->getMimeSubtype() : ""; } - void IAXVoIPLink::iaxOutgoingInvite(IAXCall* call) { diff --git a/daemon/src/iax/iaxvoiplink.h b/daemon/src/iax/iaxvoiplink.h index d633dbb379de2095831e6cb3d5d355b6c2b313a7..cd8c6efca5bab83b19465065df1ede38bfa81344 100644 --- a/daemon/src/iax/iaxvoiplink.h +++ b/daemon/src/iax/iaxvoiplink.h @@ -39,10 +39,6 @@ #include "noncopyable.h" #include "audio/samplerateconverter.h" -namespace sfl { -class InstantMessaging; -} - class EventThread; class IAXCall; @@ -167,7 +163,7 @@ class IAXVoIPLink : public VoIPLink { virtual void carryingDTMFdigits(const std::string& id, char code); - virtual void sendTextMessage(sfl::InstantMessaging &module, const std::string& callID, const std::string& message, const std::string& from); + virtual void sendTextMessage(const std::string& callID, const std::string& message, const std::string& from); /** * Return the codec protocol used for this call diff --git a/daemon/src/im/instant_messaging.cpp b/daemon/src/im/instant_messaging.cpp index 8c4de04741019cb3d66e5e1755d76d244c31b216..9b86d996538871454e78bcd3e02a4395d9cdc650 100644 --- a/daemon/src/im/instant_messaging.cpp +++ b/daemon/src/im/instant_messaging.cpp @@ -33,9 +33,9 @@ #include "logger.h" #include "expat.h" -namespace sfl { - -static void XMLCALL startElementCallback(void *userData, const char *name, const char **atts) +namespace { +void XMLCALL +startElementCallback(void *userData, const char *name, const char **atts) { if (strcmp(name, "entry")) return; @@ -45,13 +45,15 @@ static void XMLCALL startElementCallback(void *userData, const char *name, const for (const char **att = atts; *att; att += 2) entry.insert(std::pair<std::string, std::string> (*att, *(att+1))); - (static_cast<sfl::InstantMessaging::UriList *>(userData))->push_back(entry); + static_cast<sfl::InstantMessaging::UriList *>(userData)->push_back(entry); } -static void XMLCALL endElementCallback(void * /*userData*/, const char * /*name*/) +void XMLCALL endElementCallback(void * /*userData*/, const char * /*name*/) {} +} // end anonymous namespace -bool InstantMessaging::saveMessage(const std::string& message, const std::string& author, const std::string& id, int mode) +namespace sfl { +bool InstantMessaging::saveMessage(const std::string &message, const std::string &author, const std::string &id, int mode) { std::ofstream File; std::string filename = "im:" + id; @@ -81,24 +83,22 @@ void InstantMessaging::sip_send(pjsip_inv_session *session, const std::string& i return; } - const pj_str_t type = pj_str((char*)"text"); - - const pj_str_t subtype = pj_str((char*)"plain"); + const pj_str_t type = pj_str((char*) "text"); + const pj_str_t subtype = pj_str((char*) "plain"); pj_str_t message = pj_str((char*) text.c_str()); tdata->msg->body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &message); pjsip_dlg_send_request(dialog, tdata, -1, NULL); - pjsip_dlg_dec_lock(dialog); saveMessage(text, "Me", id); } -void InstantMessaging::send_sip_message(pjsip_inv_session *session, const std::string& id, const std::string& message) +void InstantMessaging::send_sip_message(pjsip_inv_session *session, const std::string &id, const std::string &message) { - std::vector<std::string> msgs = split_message(message); + std::vector<std::string> msgs(split_message(message)); std::vector<std::string>::const_iterator iter; for (iter = msgs.begin(); iter != msgs.end(); ++iter) @@ -106,9 +106,9 @@ void InstantMessaging::send_sip_message(pjsip_inv_session *session, const std::s } -void InstantMessaging::send_iax_message(iax_session* session, const std::string& /* id */, const std::string& message) +void InstantMessaging::send_iax_message(iax_session *session, const std::string &/* id */, const std::string &message) { - std::vector<std::string> msgs = split_message(message); + std::vector<std::string> msgs(split_message(message)); std::vector<std::string>::const_iterator iter; for (iter = msgs.begin(); iter != msgs.end(); ++iter) @@ -119,7 +119,7 @@ void InstantMessaging::send_iax_message(iax_session* session, const std::string& std::vector<std::string> InstantMessaging::split_message(std::string text) { std::vector<std::string> messages; - size_t len = getMessageMaximumSize(); + size_t len = MAXIMUM_MESSAGE_LENGTH; while (text.length() > len - 2) { messages.push_back(text.substr(len - 2) + "\n\n"); @@ -131,11 +131,11 @@ std::vector<std::string> InstantMessaging::split_message(std::string text) return messages; } -std::string InstantMessaging::generateXmlUriList(UriList& list) +std::string InstantMessaging::generateXmlUriList(UriList &list) { std::string xmlbuffer = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" - "<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\" xmlns:cp=\"urn:ietf:params:xml:ns:copycontrol\">" - "<list>"; + "<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\" xmlns:cp=\"urn:ietf:params:xml:ns:copycontrol\">" + "<list>"; for (UriList::iterator iter = list.begin(); iter != list.end(); ++iter) xmlbuffer += "<entry uri=" + (*iter)[sfl::IM_XML_URI] + " cp:copyControl=\"to\" />"; @@ -144,7 +144,8 @@ std::string InstantMessaging::generateXmlUriList(UriList& list) } -InstantMessaging::UriList InstantMessaging::parseXmlUriList(std::string& urilist) +InstantMessaging::UriList +InstantMessaging::parseXmlUriList(const std::string &urilist) { InstantMessaging::UriList list; @@ -161,27 +162,22 @@ InstantMessaging::UriList InstantMessaging::parseXmlUriList(std::string& urilist return list; } -std::string InstantMessaging::appendUriList(std::string text, UriList& list) +std::string InstantMessaging::appendUriList(const std::string &text, UriList& list) { - return - "--boundary Content-Type: text/plain" + - text + - "--boundary Content-Type: application/resource-lists+xml" + - "Content-Disposition: recipient-list" + - generateXmlUriList(list) + - "--boundary--"; + return "--boundary Content-Type: text/plain" + text + + "--boundary Content-Type: application/resource-lists+xml" + + "Content-Disposition: recipient-list" + generateXmlUriList(list) + + "--boundary--"; } -std::string InstantMessaging::findTextUriList(std::string& text) +std::string InstantMessaging::findTextUriList(const std::string &text) { - std::string ctype = "Content-Type: application/resource-lists+xml"; - std::string cdispo = "Content-Disposition: recipient-list"; - std::string boundary = ("--boundary--"); + const std::string ctype("Content-Type: application/resource-lists+xml"); + const std::string cdispo("Content-Disposition: recipient-list"); + const std::string boundary("--boundary--"); // init position pointer size_t pos = 0; - size_t begin = 0; - size_t end = 0; // find the content type if ((pos = text.find(ctype)) == std::string::npos) @@ -192,32 +188,30 @@ std::string InstantMessaging::findTextUriList(std::string& text) throw InstantMessageException("Could not find Content-Disposition tag while parsing sip message for recipient-list"); // xml content start after content disposition tag (plus \n\n) - begin = pos+cdispo.size(); + const size_t begin = pos + cdispo.size(); // find final boundary + size_t end; if ((end = text.find(boundary, begin)) == std::string::npos) throw InstantMessageException("Could not find final \"boundary\" while parsing sip message for recipient-list"); - return text.substr(begin, end-begin); + return text.substr(begin, end - begin); } -std::string InstantMessaging::findTextMessage(std::string& text) +std::string InstantMessaging::findTextMessage(const std::string &text) { std::string ctype = "Content-Type: text/plain"; - - size_t pos = text.find(ctype); - + const size_t pos = text.find(ctype); if (pos == std::string::npos) throw InstantMessageException("Could not find Content-Type tag while parsing sip message for text"); - size_t begin = pos+ctype.size(); - - size_t end = text.find("--boundary", begin); + const size_t begin = pos + ctype.size(); + const size_t end = text.find("--boundary", begin); if (end == std::string::npos) throw InstantMessageException("Could not find end of text \"boundary\" while parsing sip message for text"); - return text.substr(begin, end-begin); + return text.substr(begin, end - begin); } diff --git a/daemon/src/im/instant_messaging.h b/daemon/src/im/instant_messaging.h index 17018b56ca0a03eef17d1620de1c4e51eb8b4267..be0a71ce354d117f4db8b9df7762fb6f35af1efe 100644 --- a/daemon/src/im/instant_messaging.h +++ b/daemon/src/im/instant_messaging.h @@ -66,18 +66,9 @@ class InstantMessageException : public std::runtime_error { std::runtime_error("InstantMessageException occured: " + str) {} }; -class InstantMessaging { - public: - typedef std::map <std::string, std::string> UriEntry; - typedef std::list <UriEntry> UriList; - - /** - * Return the maximum number if character for a single SIP MESSAGE. - * Longer messages should be splitted in several smaller messages using split_message - */ - static size_t getMessageMaximumSize() { - return MAXIMUM_MESSAGE_LENGTH; - } +namespace InstantMessaging { + typedef std::map<std::string, std::string> UriEntry; + typedef std::list<UriEntry> UriList; /* * Write the text message to the right file @@ -102,7 +93,6 @@ class InstantMessaging { std::vector<std::string> split_message(std::string); - /** * Generate Xml participant list for multi recipient based on RFC Draft 5365 * @@ -111,7 +101,7 @@ class InstantMessaging { * @return A string containing the full XML formated information to be included in the * sip instant message. */ - std::string generateXmlUriList(UriList& list); + std::string generateXmlUriList(UriList &list); /** * Parse the Urilist from a SIP Instant Message provided by a UriList service. @@ -120,7 +110,7 @@ class InstantMessaging { * * @return An UriList of UriEntry containing parsed XML information as a map. */ - UriList parseXmlUriList(std::string& urilist); + UriList parseXmlUriList(const std::string &urilist); /** * Format text message according to RFC 5365, append recipient-list to the message @@ -130,7 +120,7 @@ class InstantMessaging { * * @return formated text stored into a string to be included in sip MESSAGE */ - std::string appendUriList(std::string text, UriList& list); + std::string appendUriList(const std::string &text, UriList &list); /** * Retreive the xml formated uri list in formated text data according to RFC 5365 @@ -139,7 +129,7 @@ class InstantMessaging { * * @return A string containing the XML content */ - std::string findTextUriList(std::string& text); + std::string findTextUriList(const std::string &text); /** * Retrive the plain text message in formated text data according to RFC 5365 @@ -148,7 +138,7 @@ class InstantMessaging { * * @return A string containing the actual message */ - std::string findTextMessage(std::string& text); -}; + std::string findTextMessage(const std::string &text); +} // end namespace InstantMessaging } #endif // __INSTANT_MESSAGING_H_ diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp index 264f0e623e479f995f8186526c019ab014bfaa6f..0d13a8bc4612b05c4db0ff8ebf4049d599fd0576 100644 --- a/daemon/src/managerimpl.cpp +++ b/daemon/src/managerimpl.cpp @@ -32,7 +32,9 @@ * as that of the covered work. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include "managerimpl.h" @@ -43,13 +45,13 @@ #include "im/instant_messaging.h" #include "iax/iaxaccount.h" #include "numbercleaner.h" - +#include "config/yamlparser.h" +#include "config/yamlemitter.h" #include "audio/alsa/alsalayer.h" #include "audio/pulseaudio/pulselayer.h" #include "audio/sound/tonelist.h" #include "audio/sound/audiofile.h" #include "audio/sound/dtmf.h" -#include "history/history.h" #include "sip/sipvoiplink.h" #include "iax/iaxvoiplink.h" #include "manager.h" @@ -59,9 +61,11 @@ #include "conference.h" #include <cerrno> +#include <algorithm> #include <ctime> #include <cstdlib> #include <iostream> +#include <tr1/functional> #include <iterator> #include <fstream> #include <sstream> @@ -76,8 +80,7 @@ ManagerImpl::ManagerImpl() : toneMutex_(), telephoneTone_(0), audiofile_(0), audioLayerMutex_(), waitingCall_(), waitingCallMutex_(), nbIncomingWaitingCall_(0), path_(), callAccountMap_(), callAccountMapMutex_(), IPToIPMap_(), accountMap_(), - mainBuffer_(), conferenceMap_(), history_(new History), - imModule_(new sfl::InstantMessaging) + mainBuffer_(), conferenceMap_(), history_() { // initialize random generator for call id srand(time(NULL)); @@ -92,22 +95,18 @@ void ManagerImpl::init(std::string config_file) path_ = config_file.empty() ? createConfigFile() : config_file; DEBUG("Manager: configuration file path: %s", path_.c_str()); - Conf::YamlParser *parser = NULL; try { - parser = new Conf::YamlParser(path_.c_str()); - parser->serializeEvents(); - parser->composeEvents(); - parser->constructNativeData(); + Conf::YamlParser parser(path_.c_str()); + parser.serializeEvents(); + parser.composeEvents(); + parser.constructNativeData(); + loadAccountMap(parser); } catch (const Conf::YamlParserException &e) { ERROR("Manager: %s", e.what()); fflush(stderr); - delete parser; - parser = NULL; + loadDefaultAccountMap(); } - loadAccountMap(parser); - delete parser; - initAudioDriver(); { @@ -118,7 +117,7 @@ void ManagerImpl::init(std::string config_file) } } - history_->load(preferences.getHistoryLimit()); + history_.load(preferences.getHistoryLimit()); registerAccounts(); } @@ -364,7 +363,7 @@ void ManagerImpl::hangupCall(const std::string& callId) /* Direct IP to IP call */ try { Call * call = SIPVoIPLink::instance()->getCall(callId); - history_->addCall(call, preferences.getHistoryLimit()); + history_.addCall(call, preferences.getHistoryLimit()); SIPVoIPLink::instance()->hangup(callId); } catch (const VoipLinkException &e) { ERROR("%s", e.what()); @@ -373,7 +372,7 @@ void ManagerImpl::hangupCall(const std::string& callId) std::string accountId(getAccountFromCall(callId)); VoIPLink *link = getAccountLink(accountId); Call * call = link->getCall(callId); - history_->addCall(call, preferences.getHistoryLimit()); + history_.addCall(call, preferences.getHistoryLimit()); link->hangup(callId); removeCallAccount(callId); } @@ -1352,11 +1351,6 @@ void ManagerImpl::removeWaitingCall(const std::string& id) nbIncomingWaitingCall_--; } -bool ManagerImpl::isWaitingCall(const std::string &id) const -{ - return waitingCall_.find(id) != waitingCall_.end(); -} - /////////////////////////////////////////////////////////////////////////////// // Management of event peer IP-phone //////////////////////////////////////////////////////////////////////////////// @@ -1423,7 +1417,7 @@ void ManagerImpl::incomingMessage(const std::string& callID, return; } - account->getVoIPLink()->sendTextMessage(*imModule_, callID, message, from); + account->getVoIPLink()->sendTextMessage(callID, message, from); } // in case of a conference we must notify client using conference id @@ -1463,7 +1457,7 @@ bool ManagerImpl::sendTextMessage(const std::string& callID, const std::string& return false; } - account->getVoIPLink()->sendTextMessage(*imModule_, *iter_p, message, from); + account->getVoIPLink()->sendTextMessage(*iter_p, message, from); } return true; @@ -1490,7 +1484,7 @@ bool ManagerImpl::sendTextMessage(const std::string& callID, const std::string& return false; } - account->getVoIPLink()->sendTextMessage(*imModule_, *iter_p, message, from); + account->getVoIPLink()->sendTextMessage(*iter_p, message, from); } } else { Account *account = getAccount(getAccountFromCall(callID)); @@ -1500,7 +1494,7 @@ bool ManagerImpl::sendTextMessage(const std::string& callID, const std::string& return false; } - account->getVoIPLink()->sendTextMessage(*imModule_, callID, message, from); + account->getVoIPLink()->sendTextMessage(callID, message, from); } return true; @@ -1564,14 +1558,14 @@ void ManagerImpl::peerHungupCall(const std::string& call_id) /* Direct IP to IP call */ if (isIPToIP(call_id)) { Call * call = SIPVoIPLink::instance()->getCall(call_id); - history_->addCall(call, preferences.getHistoryLimit()); + history_.addCall(call, preferences.getHistoryLimit()); SIPVoIPLink::instance()->hangup(call_id); } else { const std::string account_id(getAccountFromCall(call_id)); VoIPLink *link = getAccountLink(account_id); Call * call = link->getCall(call_id); - history_->addCall(call, preferences.getHistoryLimit()); + history_.addCall(call, preferences.getHistoryLimit()); link->peerHungup(call_id); } @@ -2570,27 +2564,71 @@ std::vector<std::string> ManagerImpl::loadAccountOrder() const return unserialize(preferences.getAccountOrder()); } -void ManagerImpl::loadAccountMap(Conf::YamlParser *parser) +void ManagerImpl::loadDefaultAccountMap() { // build a default IP2IP account with default parameters - Account *ip2ip = new SIPAccount(IP2IP_PROFILE); - accountMap_[IP2IP_PROFILE] = ip2ip; + accountMap_[IP2IP_PROFILE] = new SIPAccount(IP2IP_PROFILE); + SIPVoIPLink::instance()->createDefaultSipUdpTransport(); + accountMap_[IP2IP_PROFILE]->registerVoIPLink(); +} - // If configuration file parsed, load saved preferences - if (parser) { - Conf::Sequence *seq = parser->getAccountSequence()->getSequence(); +namespace { + bool isIP2IP(const Conf::YamlNode *node) + { + std::string id; + dynamic_cast<const Conf::MappingNode *>(node)->getValue("id", &id); + return id == "IP2IP"; + } - for (Conf::Sequence::const_iterator iter = seq->begin(); iter != seq->end(); ++iter) { - Conf::MappingNode *map = (Conf::MappingNode *)(*iter); - std::string accountid; - map->getValue("id", &accountid); + void loadAccount(const Conf::YamlNode *item, AccountMap &accountMap) + { + const Conf::MappingNode *node = dynamic_cast<const Conf::MappingNode *>(item); + std::string accountType; + node->getValue("type", &accountType); - if (accountid == "IP2IP") { - ip2ip->unserialize(map); - break; - } + std::string accountid; + node->getValue("id", &accountid); + + std::string accountAlias; + node->getValue("alias", &accountAlias); + + if (!accountid.empty() and !accountAlias.empty() and accountid != IP2IP_PROFILE) { + Account *a; +#if HAVE_IAX + if (accountType == "IAX") + a = new IAXAccount(accountid); + else // assume SIP +#endif + a = new SIPAccount(accountid); + + accountMap[accountid] = a; + a->unserialize(node); + } + } + + void unloadAccount(std::pair<const std::string, Account*> &item) + { + // avoid deleting IP2IP account twice + if (not item.first.empty()) { + delete item.second; + item.second = 0; } } +} // end anonymous namespace + +void ManagerImpl::loadAccountMap(Conf::YamlParser &parser) +{ + using namespace Conf; + // build a default IP2IP account with default parameters + accountMap_[IP2IP_PROFILE] = new SIPAccount(IP2IP_PROFILE); + + // load saved preferences for IP2IP account from configuration file + Sequence *seq = parser.getAccountSequence()->getSequence(); + Sequence::const_iterator ip2ip = std::find_if(seq->begin(), seq->end(), isIP2IP); + if (ip2ip != seq->end()) { + MappingNode *node = dynamic_cast<MappingNode*>(*ip2ip); + accountMap_[IP2IP_PROFILE]->unserialize(node); + } // Initialize default UDP transport according to // IP to IP settings (most likely using port 5060) @@ -2598,66 +2636,29 @@ void ManagerImpl::loadAccountMap(Conf::YamlParser *parser) // Force IP2IP settings to be loaded to be loaded // No registration in the sense of the REGISTER method is performed. - ip2ip->registerVoIPLink(); - - if (!parser) - return; + accountMap_[IP2IP_PROFILE]->registerVoIPLink(); // build preferences - preferences.unserialize(parser->getPreferenceNode()); - voipPreferences.unserialize(parser->getVoipPreferenceNode()); - addressbookPreference.unserialize(parser->getAddressbookNode()); - hookPreference.unserialize(parser->getHookNode()); - audioPreference.unserialize(parser->getAudioNode()); - shortcutPreferences.unserialize(parser->getShortcutNode()); - - Conf::Sequence *seq = parser->getAccountSequence()->getSequence(); - - // Each element in sequence is a new account to create - for (Conf::Sequence::const_iterator iter = seq->begin(); iter != seq->end(); ++iter) { - Conf::MappingNode *map = (Conf::MappingNode *)(*iter); - - std::string accountType; - map->getValue("type", &accountType); - - std::string accountid; - map->getValue("id", &accountid); + preferences.unserialize(parser.getPreferenceNode()); + voipPreferences.unserialize(parser.getVoipPreferenceNode()); + addressbookPreference.unserialize(parser.getAddressbookNode()); + hookPreference.unserialize(parser.getHookNode()); + audioPreference.unserialize(parser.getAudioNode()); + shortcutPreferences.unserialize(parser.getShortcutNode()); - std::string accountAlias; - map->getValue("alias", &accountAlias); - - if (accountid.empty() or accountAlias.empty() or accountid == IP2IP_PROFILE) - continue; - - Account *a; - -#if HAVE_IAX - if (accountType == "IAX") - a = new IAXAccount(accountid); - else // assume SIP -#endif - a = new SIPAccount(accountid); - - accountMap_[accountid] = a; - - a->unserialize(map); - } + using namespace std::tr1; // for std::tr1::bind and std::tr1::ref + using namespace std::tr1::placeholders; + // Each valid account element in sequence is a new account to load + std::for_each(seq->begin(), seq->end(), bind(loadAccount, _1, ref(accountMap_))); } void ManagerImpl::unloadAccountMap() { - for (AccountMap::iterator iter = accountMap_.begin(); iter != accountMap_.end(); ++iter) { - // Avoid removing the IP2IP account twice - if (not iter->first.empty()) { - delete iter->second; - iter->second = 0; - } - } - + std::for_each(accountMap_.begin(), accountMap_.end(), unloadAccount); accountMap_.clear(); } -bool ManagerImpl::accountExists(const std::string& accountID) +bool ManagerImpl::accountExists(const std::string &accountID) { return accountMap_.find(accountID) != accountMap_.end(); } @@ -2782,7 +2783,7 @@ bool ManagerImpl::isIPToIP(const std::string& callID) const return iter != IPToIPMap_.end() and iter->second; } -std::map<std::string, std::string> ManagerImpl::getCallDetails(const std::string& callID) +std::map<std::string, std::string> ManagerImpl::getCallDetails(const std::string &callID) { // We need here to retrieve the call information attached to the call ID // To achieve that, we need to get the voip link attached to the call @@ -2826,7 +2827,7 @@ std::map<std::string, std::string> ManagerImpl::getCallDetails(const std::string std::vector<std::map<std::string, std::string> > ManagerImpl::getHistory() const { - return history_->getSerialized(); + return history_.getSerialized(); } namespace { @@ -2882,11 +2883,11 @@ std::vector<std::string> ManagerImpl::getParticipantList(const std::string& conf void ManagerImpl::saveHistory() { - if (!history_->save()) + if (!history_.save()) ERROR("Manager: could not save history!"); } void ManagerImpl::clearHistory() { - history_->clear(); + history_.clear(); } diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h index 97f3c5714068bca4c6bd6a10911d045a56223474..c8daee1dcaf392ccf7255e6ec9fd9284d4ba1c61 100644 --- a/daemon/src/managerimpl.h +++ b/daemon/src/managerimpl.h @@ -53,15 +53,12 @@ #include "audio/mainbuffer.h" #include "preferences.h" +#include "history/history.h" #include "noncopyable.h" -namespace sfl { -class InstantMessaging; -} - namespace Conf { -class YamlParser; -class YamlEmitter; + class YamlParser; + class YamlEmitter; } class DTMF; @@ -955,13 +952,6 @@ class ManagerImpl { */ void removeWaitingCall(const std::string& id); - /** - * Tell if a call is waiting and should be remove - * @param id std::string to test - * @return bool True if the call is waiting - */ - bool isWaitingCall(const std::string& id) const; - /** Remove a CallID/std::string association * Protected by mutex * @param callID the CallID to remove @@ -996,9 +986,13 @@ class ManagerImpl { AccountMap accountMap_; /** - * Load the account from configuration + * Load the account map from configuration + */ + void loadAccountMap(Conf::YamlParser &parser); + /** + * Load default account map (no configuration) */ - void loadAccountMap(Conf::YamlParser *parser); + void loadDefaultAccountMap(); /** * Unload the account (delete them) @@ -1039,13 +1033,6 @@ class ManagerImpl { return &mainBuffer_; } - /** - * Return a pointer to the instance of InstantMessaging - */ - sfl::InstantMessaging &getInstantMessageModule() { - return *imModule_; - } - /** * Tell if there is a current call processed * @return bool True if there is a current call @@ -1116,13 +1103,6 @@ class ManagerImpl { * To handle the persistent history * TODO: move this to ConfigurationManager */ - std::auto_ptr<History> history_; - - /** - * Instant messaging module, resposible to initiate, format, parse, - * send, and receive instant messages. - */ - std::auto_ptr<sfl::InstantMessaging> imModule_; + History history_; }; - #endif // __MANAGER_H__ diff --git a/daemon/src/preferences.cpp b/daemon/src/preferences.cpp index 98f36f2a2a5dd9e3476b49634af9fbf3958f941a..7b8f93dc97ebfa328719e28e7a72db05ead5e9db 100644 --- a/daemon/src/preferences.cpp +++ b/daemon/src/preferences.cpp @@ -31,6 +31,8 @@ #include "preferences.h" #include "audio/alsa/alsalayer.h" #include "audio/pulseaudio/pulselayer.h" +#include "config/yamlemitter.h" +#include "config/yamlnode.h" #include <sstream> #include "global.h" #include <cassert> @@ -94,7 +96,7 @@ void Preferences::serialize(Conf::YamlEmitter *emiter) emiter->serializePreference(&preferencemap); } -void Preferences::unserialize(Conf::MappingNode *map) +void Preferences::unserialize(const Conf::MappingNode *map) { if (map == NULL) { ERROR("Preference: Error: Preference map is NULL"); @@ -141,7 +143,7 @@ void VoipPreference::serialize(Conf::YamlEmitter *emitter) emitter->serializeVoipPreference(&preferencemap); } -void VoipPreference::unserialize(Conf::MappingNode *map) +void VoipPreference::unserialize(const Conf::MappingNode *map) { if (!map) { ERROR("VoipPreference: Error: Preference map is NULL"); @@ -190,7 +192,7 @@ void AddressbookPreference::serialize(Conf::YamlEmitter *emitter) } -void AddressbookPreference::unserialize(Conf::MappingNode *map) +void AddressbookPreference::unserialize(const Conf::MappingNode *map) { if (!map) { ERROR("Addressbook: Error: Preference map is NULL"); @@ -235,7 +237,7 @@ void HookPreference::serialize(Conf::YamlEmitter *emitter) emitter->serializeHooksPreference(&preferencemap); } -void HookPreference::unserialize(Conf::MappingNode *map) +void HookPreference::unserialize(const Conf::MappingNode *map) { if (!map) { ERROR("Hook: Error: Preference map is NULL"); @@ -377,7 +379,7 @@ void AudioPreference::serialize(Conf::YamlEmitter *emitter) emitter->serializeAudioPreference(&preferencemap); } -void AudioPreference::unserialize(Conf::MappingNode *map) +void AudioPreference::unserialize(const Conf::MappingNode *map) { assert(map); @@ -454,7 +456,7 @@ void ShortcutPreferences::serialize(Conf::YamlEmitter *emitter) emitter->serializeShortcutPreference(&preferencemap); } -void ShortcutPreferences::unserialize(Conf::MappingNode *map) +void ShortcutPreferences::unserialize(const Conf::MappingNode *map) { if (map == NULL) { ERROR("ShortcutPreference: Error: Preference map is NULL"); diff --git a/daemon/src/preferences.h b/daemon/src/preferences.h index e4e99a4e11cdd6d02e94fad55cdd1c935e3823e6..8b176a579f56c1e28b7db4e3df5481e647fc20fa 100644 --- a/daemon/src/preferences.h +++ b/daemon/src/preferences.h @@ -32,6 +32,8 @@ #define __PREFERENCE_H__ #include "config/serializable.h" +#include <string> +#include <map> // general preferences static const char * const orderKey = "order"; @@ -107,7 +109,7 @@ class Preferences : public Serializable { virtual void serialize(Conf::YamlEmitter *emitter); - virtual void unserialize(Conf::MappingNode *map); + virtual void unserialize(const Conf::MappingNode *map); std::string getAccountOrder() const { return accountOrder_; @@ -206,7 +208,7 @@ class VoipPreference : public Serializable { virtual void serialize(Conf::YamlEmitter *emitter); - virtual void unserialize(Conf::MappingNode *map); + virtual void unserialize(const Conf::MappingNode *map); bool getPlayDtmf() const { return playDtmf_; @@ -261,7 +263,7 @@ class AddressbookPreference : public Serializable { virtual void serialize(Conf::YamlEmitter *emitter); - virtual void unserialize(Conf::MappingNode *map); + virtual void unserialize(const Conf::MappingNode *map); bool getPhoto() const { return photo_; @@ -336,7 +338,7 @@ class HookPreference : public Serializable { virtual void serialize(Conf::YamlEmitter *emitter); - virtual void unserialize(Conf::MappingNode *map); + virtual void unserialize(const Conf::MappingNode *map); bool getIax2Enabled() const { return iax2Enabled_; @@ -410,7 +412,7 @@ class AudioPreference : public Serializable { virtual void serialize(Conf::YamlEmitter *emitter); - virtual void unserialize(Conf::MappingNode *map); + virtual void unserialize(const Conf::MappingNode *map); // alsa preference int getCardin() const { @@ -568,7 +570,7 @@ class ShortcutPreferences : public Serializable { public: ShortcutPreferences(); virtual void serialize(Conf::YamlEmitter *emitter); - virtual void unserialize(Conf::MappingNode *map); + virtual void unserialize(const Conf::MappingNode *map); void setShortcuts(std::map<std::string, std::string> shortcuts); std::map<std::string, std::string> getShortcuts() const; diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp index b5f2275f89d0653cb932ea2c6440958a4d93c043..23848f2b2a1d16085119de209dbba1a178604342 100644 --- a/daemon/src/sip/sipaccount.cpp +++ b/daemon/src/sip/sipaccount.cpp @@ -30,10 +30,15 @@ * as that of the covered work. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "sipaccount.h" #include "sipvoiplink.h" +#include "config/yamlnode.h" +#include "config/yamlemitter.h" #include "manager.h" -#include "config.h" #include <pwd.h> #include <sstream> #include <cassert> @@ -250,7 +255,7 @@ void SIPAccount::serialize(Conf::YamlEmitter *emitter) } -void SIPAccount::unserialize(Conf::MappingNode *map) +void SIPAccount::unserialize(const Conf::MappingNode *map) { using namespace Conf; MappingNode *srtpMap; diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h index 94986a5ae8bd8da62c4b9136a0a214a6405fc6fd..0eed0065bd61dd4dc76bcf129eeaaea9ff0c164d 100644 --- a/daemon/src/sip/sipaccount.h +++ b/daemon/src/sip/sipaccount.h @@ -131,7 +131,7 @@ class SIPAccount : public Account { * Populate the internal state for this account based on info stored in the configuration file * @param The configuration node for this account */ - virtual void unserialize(Conf::MappingNode *map); + virtual void unserialize(const Conf::MappingNode *map); /** * Set the internal state for this account, mainly used to manage account details from the client application. diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp index e943434d93fab8ecc8e50efd38a8261a41a159a0..73518592a9e988e0e0e436ea06741d5519cf2a73 100644 --- a/daemon/src/sip/sipvoiplink.cpp +++ b/daemon/src/sip/sipvoiplink.cpp @@ -876,11 +876,11 @@ SIPVoIPLink::offhold(const std::string& id) call->setState(Call::ACTIVE); } -void SIPVoIPLink::sendTextMessage(sfl::InstantMessaging &module, - const std::string &callID, +void SIPVoIPLink::sendTextMessage(const std::string &callID, const std::string &message, const std::string &from) { + using namespace sfl::InstantMessaging; SIPCall *call; try { @@ -890,11 +890,11 @@ void SIPVoIPLink::sendTextMessage(sfl::InstantMessaging &module, } /* Send IM message */ - sfl::InstantMessaging::UriList list; - sfl::InstantMessaging::UriEntry entry; + UriList list; + UriEntry entry; entry[sfl::IM_XML_URI] = std::string("\"" + from + "\""); // add double quotes for xml formating list.push_front(entry); - module.send_sip_message(call->inv, callID, module.appendUriList(message, list)); + send_sip_message(call->inv, callID, appendUriList(message, list)); } bool @@ -1846,12 +1846,12 @@ void transaction_state_changed_cb(pjsip_inv_session *inv UNUSED, pjsip_transacti pjsip_dlg_create_response(inv->dlg, r_data, PJSIP_SC_OK, NULL, &t_data); pjsip_dlg_send_response(inv->dlg, tsx, t_data); - sfl::InstantMessaging &module = Manager::instance().getInstantMessageModule(); + using namespace sfl::InstantMessaging; try { // retreive the recipient-list of this message - std::string urilist = module.findTextUriList(formattedMessage); - sfl::InstantMessaging::UriList list = module.parseXmlUriList(urilist); + std::string urilist = findTextUriList(formattedMessage); + UriList list = parseXmlUriList(urilist); // If no item present in the list, peer is considered as the sender std::string from; @@ -1869,7 +1869,7 @@ void transaction_state_changed_cb(pjsip_inv_session *inv UNUSED, pjsip_transacti if (from[0] == '<' && from[from.size()-1] == '>') from = from.substr(1, from.size()-2); - Manager::instance().incomingMessage(call->getCallId(), from, module.findTextMessage(formattedMessage)); + Manager::instance().incomingMessage(call->getCallId(), from, findTextMessage(formattedMessage)); } catch (const sfl::InstantMessageException &except) { ERROR("SipVoipLink: %s", except.what()); diff --git a/daemon/src/sip/sipvoiplink.h b/daemon/src/sip/sipvoiplink.h index c40e8eb3bec09074f2d8109c9db33a3c634ba84e..e5869b674a28bbe62077481161e14e3ee2bd9ea1 100644 --- a/daemon/src/sip/sipvoiplink.h +++ b/daemon/src/sip/sipvoiplink.h @@ -49,10 +49,6 @@ #include "sipaccount.h" #include "voiplink.h" -namespace sfl { -class InstantMessaging; -} - class EventThread; class SIPCall; class SIPAccount; @@ -270,13 +266,11 @@ class SIPVoIPLink : public VoIPLink { /** * Send a SIP message to a call identified by its callid * - * @param The InstantMessaging module which contains formating, parsing and sending method * @param The Id of the call to send the message to * @param The actual message to be transmitted * @param The sender of this message (could be another participant of a conference) */ - void sendTextMessage(sfl::InstantMessaging &module, - const std::string& callID, + void sendTextMessage(const std::string& callID, const std::string& message, const std::string& from); diff --git a/daemon/src/voiplink.h b/daemon/src/voiplink.h index 2df49ba924b609fb49b5c48aa689f8a1b368e1d7..957de09c120656508eaf28c2779e7baca538f677 100644 --- a/daemon/src/voiplink.h +++ b/daemon/src/voiplink.h @@ -41,10 +41,6 @@ class Call; class Account; -namespace sfl { -class InstantMessaging; -}; - /** Define a map that associate a Call object to a call identifier */ typedef std::map<std::string, Call*> CallMap; @@ -165,13 +161,11 @@ class VoIPLink { /** * Send a message to a call identified by its callid * - * @param The InstantMessaging module which contains formating, parsing and sending method * @param The Id of the call to send the message to * @param The actual message to be transmitted * @param The sender of this message (could be another participant of a conference) */ - virtual void sendTextMessage(sfl::InstantMessaging &module, - const std::string &callID, + virtual void sendTextMessage(const std::string &callID, const std::string &message, const std::string &from) = 0; diff --git a/daemon/test/instantmessagingtest.cpp b/daemon/test/instantmessagingtest.cpp index 89f0041a3f465f168c1d798a37c14d1fa448bc81..d88185d01ee29bfc9299c556902fdf6517abfe95 100644 --- a/daemon/test/instantmessagingtest.cpp +++ b/daemon/test/instantmessagingtest.cpp @@ -28,26 +28,21 @@ * as that of the covered work. */ -#include <stdio.h> #include <iostream> #include <fstream> #include "instantmessagingtest.h" +#include "im/instant_messaging.h" #include "expat.h" -#include <stdio.h> +#include <cstdio> #define MAXIMUM_SIZE 10 #define DELIMITER_CHAR "\n\n" using std::cout; using std::endl; - - -void InstantMessagingTest::setUp() -{ - im_ = new sfl::InstantMessaging(); -} +using namespace sfl::InstantMessaging; void InstantMessagingTest::testSaveSingleMessage() { @@ -58,7 +53,7 @@ void InstantMessagingTest::testSaveSingleMessage() std::string filename = "im:"; // Open a file stream and try to write in it - CPPUNIT_ASSERT(im_->saveMessage("Bonjour, c'est un test d'archivage de message", "Manu", callID, std::ios::out) == true); + CPPUNIT_ASSERT(saveMessage("Bonjour, c'est un test d'archivage de message", "Manu", callID, std::ios::out) == true); filename.append(callID); // Read it to check it has been successfully written @@ -83,8 +78,8 @@ void InstantMessagingTest::testSaveMultipleMessage() std::string filename = "im:"; // Open a file stream and try to write in it - CPPUNIT_ASSERT(im_->saveMessage("Bonjour, c'est un test d'archivage de message", "Manu", callID, std::ios::out) == true); - CPPUNIT_ASSERT(im_->saveMessage("Cool", "Alex", callID, std::ios::out || std::ios::app) == true); + CPPUNIT_ASSERT(saveMessage("Bonjour, c'est un test d'archivage de message", "Manu", callID, std::ios::out) == true); + CPPUNIT_ASSERT(saveMessage("Cool", "Alex", callID, std::ios::out || std::ios::app) == true); filename.append(callID); // Read it to check it has been successfully written @@ -140,17 +135,14 @@ static void XMLCALL startElementCallback(void *userData, const char *name, const } *nbEntry += 1; - } -static void XMLCALL endElementCallback(void * /*userData*/, const char * /*name*/) -{ - // std::cout << "endElement " << name << std::endl; -} +static void XMLCALL +endElementCallback(void * /*userData*/, const char * /*name*/) +{} void InstantMessagingTest::testGenerateXmlUriList() { - std::cout << std::endl; // Create a test list with two entries @@ -165,7 +157,7 @@ void InstantMessagingTest::testGenerateXmlUriList() list.push_front(entry1); list.push_front(entry2); - std::string buffer = im_->generateXmlUriList(list); + std::string buffer = generateXmlUriList(list); CPPUNIT_ASSERT(buffer.size() != 0); std::cout << buffer << std::endl; @@ -185,8 +177,6 @@ void InstantMessagingTest::testGenerateXmlUriList() XML_ParserFree(parser); CPPUNIT_ASSERT(nbEntry == 4); - - CPPUNIT_ASSERT(true); } void InstantMessagingTest::testXmlUriListParsing() @@ -200,7 +190,7 @@ void InstantMessagingTest::testXmlUriListParsing() xmlbuffer.append("</resource-lists>"); - sfl::InstantMessaging::UriList list = im_->parseXmlUriList(xmlbuffer); + sfl::InstantMessaging::UriList list = parseXmlUriList(xmlbuffer); CPPUNIT_ASSERT(list.size() == 2); // An iterator over xml attribute @@ -241,14 +231,13 @@ void InstantMessagingTest::testGetTextArea() formatedText.append("</resource-lists>"); formatedText.append("--boundary--"); - std::string message = im_->findTextMessage(formatedText); + std::string message = findTextMessage(formatedText); std::cout << "message " << message << std::endl; CPPUNIT_ASSERT(message == "Here is the text area"); } - void InstantMessagingTest::testGetUriListArea() { std::string formatedText = "--boundary Content-Type: text/plain"; @@ -265,13 +254,13 @@ void InstantMessagingTest::testGetUriListArea() formatedText.append("</resource-lists>"); formatedText.append("--boundary--"); - std::string urilist = im_->findTextUriList(formatedText); + std::string urilist = findTextUriList(formatedText); CPPUNIT_ASSERT(urilist.compare("<?xml version=\"1.0\" encoding=\"UTF-8\"?><resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\" xmlns:cp=\"urn:ietf:params:xml:ns:copycontrol\"><list><entry uri=\"sip:alex@example.com\" cp:copyControl=\"to\" /><entry uri=\"sip:manu@example.com\" cp:copyControl=\"to\" /></list></resource-lists>") == 0); std::cout << "urilist: " << urilist << std::endl; - sfl::InstantMessaging::UriList list = im_->parseXmlUriList(urilist); + sfl::InstantMessaging::UriList list = parseXmlUriList(urilist); CPPUNIT_ASSERT(list.size() == 2); // order may be important, for example to identify message sender @@ -289,7 +278,6 @@ void InstantMessagingTest::testGetUriListArea() CPPUNIT_ASSERT(from == "sip:alex@example.com"); } - void InstantMessagingTest::testIllFormatedMessage() { bool exceptionCaught = false; @@ -310,8 +298,8 @@ void InstantMessagingTest::testIllFormatedMessage() formatedText.append("--boundary--"); try { - std::string message = im_->findTextMessage(formatedText); - } catch (sfl::InstantMessageException &e) { + std::string message = findTextMessage(formatedText); + } catch (const sfl::InstantMessageException &e) { exceptionCaught = true; } @@ -319,12 +307,4 @@ void InstantMessagingTest::testIllFormatedMessage() CPPUNIT_ASSERT(true); else CPPUNIT_ASSERT(false); - -} - - -void InstantMessagingTest::tearDown() -{ - delete im_; - im_ = 0; } diff --git a/daemon/test/instantmessagingtest.h b/daemon/test/instantmessagingtest.h index 867e19eedfdcfa91424c5870b5d203e9ad04113e..0977397e6ad237928ce9e6b4953b976e24e328fa 100644 --- a/daemon/test/instantmessagingtest.h +++ b/daemon/test/instantmessagingtest.h @@ -34,25 +34,15 @@ #include <cppunit/TestCase.h> #include <cppunit/TestSuite.h> -#include <cassert> - -// Application import -#include "im/instant_messaging.h" -#include "noncopyable.h" - /* * @file instantmessagingtest.h - * @brief Regroups unitary tests related to the instant messagin module + * @brief Unit tests related to the instant messaging module */ -#ifndef _INSTANTMANAGER_TEST_ -#define _INSTANTMANAGER_TEST_ +#ifndef INSTANTMANAGER_TEST_ +#define INSTANTMANAGER_TEST_ class InstantMessagingTest : public CppUnit::TestCase { - - /** - * Use cppunit library macros to add unit test the factory - */ CPPUNIT_TEST_SUITE(InstantMessagingTest); CPPUNIT_TEST(testSaveSingleMessage); CPPUNIT_TEST(testSaveMultipleMessage); @@ -64,37 +54,15 @@ class InstantMessagingTest : public CppUnit::TestCase { CPPUNIT_TEST_SUITE_END(); public: - InstantMessagingTest() : CppUnit::TestCase("Instant messaging module Tests"), im_(0) {} - - /* - * Code factoring - Common resources can be initialized here. - * This method is called by unitcpp before each test - */ - void setUp(); - - /* - * Code factoring - Common resources can be released here. - * This method is called by unitcpp after each test - */ - void tearDown(); + InstantMessagingTest() : CppUnit::TestCase("Instant messaging module Tests") {} void testSaveSingleMessage(); - void testSaveMultipleMessage(); - void testGenerateXmlUriList(); - void testXmlUriListParsing(); - void testGetTextArea(); - void testGetUriListArea(); - void testIllFormatedMessage(); - - private: - NON_COPYABLE(InstantMessagingTest); - sfl::InstantMessaging *im_; }; /* Register our test module */ diff --git a/daemon/test/siptest.h b/daemon/test/siptest.h index 0e11f4415803612adc6d1718bbbca1ce9c2eddcb..3b5152bdfe24f955bff33c3d616d293daca676ba 100644 --- a/daemon/test/siptest.h +++ b/daemon/test/siptest.h @@ -34,8 +34,6 @@ #include <cppunit/TestCase.h> #include <cppunit/TestSuite.h> -#include <assert.h> - // Application import #include "manager.h"