summaryrefslogtreecommitdiffstats
path: root/src/im/msg_session.cpp
diff options
context:
space:
mode:
authorMichal Kubecek <mkubecek@suse.cz>2015-04-13 09:21:39 +0200
committerMichal Kubecek <mkubecek@suse.cz>2015-04-13 09:21:39 +0200
commite2bc6f4153813cc570ae814c8ddb74628009b488 (patch)
treea40b171be1d859c2232ccc94f758010f9ae54d3c /src/im/msg_session.cpp
downloadtwinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar
twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar.gz
twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar.lz
twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar.xz
twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.zip
initial checkin
Check in contents of upstream 1.4.2 tarball, exclude generated files.
Diffstat (limited to 'src/im/msg_session.cpp')
-rw-r--r--src/im/msg_session.cpp423
1 files changed, 423 insertions, 0 deletions
diff --git a/src/im/msg_session.cpp b/src/im/msg_session.cpp
new file mode 100644
index 0000000..640012f
--- /dev/null
+++ b/src/im/msg_session.cpp
@@ -0,0 +1,423 @@
+/*
+ Copyright (C) 2005-2009 Michel de Boer <michel@twinklephone.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "msg_session.h"
+
+#include <cassert>
+#include <sys/time.h>
+
+#include "im_iscomposing_body.h"
+#include "log.h"
+#include "phone.h"
+#include "translator.h"
+#include "parser/media_type.h"
+#include "utils/file_utils.h"
+
+#define COMPOSING_LOCAL_IDLE_TIMEOUT 15
+#define COMPOSING_LOCAL_REFRESH_TIMEOUT 90
+
+extern t_phone *phone;
+
+using namespace im;
+using namespace utils;
+
+t_composing_state im::string2composing_state(const string &state_name) {
+ if (state_name == IM_ISCOMPOSING_STATE_ACTIVE) {
+ return COMPOSING_STATE_ACTIVE;
+ }
+
+ return COMPOSING_STATE_IDLE;
+}
+
+string im::composing_state2string(t_composing_state state) {
+ switch (state) {
+ case COMPOSING_STATE_IDLE:
+ return "idle";
+ case COMPOSING_STATE_ACTIVE:
+ return "active";
+ default:
+ assert(false);
+ }
+
+ return "idle";
+}
+
+// class t_msg
+
+t_msg::t_msg() :
+ has_attachment(false)
+{
+ struct timeval t;
+
+ gettimeofday(&t, NULL);
+ timestamp = t.tv_sec;
+}
+
+t_msg::t_msg(const string &msg, t_direction dir, t_text_format fmt) :
+ message(msg),
+ direction(dir),
+ format(fmt),
+ has_attachment(false)
+{
+ struct timeval t;
+
+ gettimeofday(&t, NULL);
+ timestamp = t.tv_sec;
+}
+
+void t_msg::set_attachment(const string &filename, const t_media &media, const string &save_as) {
+ attachment_filename = filename;
+ attachment_media = media;
+ attachment_save_as_name = save_as;
+ has_attachment = true;
+}
+
+// class t_msg_session
+
+t_msg_session::t_msg_session(t_user *u) :
+ user_config(u),
+ new_message_added(false),
+ error_recvd(false),
+ delivery_notification_recvd(false),
+ msg_in_flight(false),
+ send_composing_state(u->get_im_send_iscomposing()),
+ local_composing_state(COMPOSING_STATE_IDLE),
+ local_idle_timeout(0),
+ local_refresh_timeout(0),
+ remote_composing_state(COMPOSING_STATE_IDLE),
+ remote_idle_timeout(0)
+{}
+
+t_msg_session::t_msg_session(t_user *u, t_display_url _remote_party) :
+ user_config(u),
+ remote_party(_remote_party),
+ new_message_added(false),
+ error_recvd(false),
+ delivery_notification_recvd(false),
+ msg_in_flight(false),
+ send_composing_state(u->get_im_send_iscomposing()),
+ local_composing_state(COMPOSING_STATE_IDLE),
+ local_idle_timeout(0),
+ local_refresh_timeout(0),
+ remote_composing_state(COMPOSING_STATE_IDLE),
+ remote_idle_timeout(0)
+{}
+
+t_msg_session::~t_msg_session() {
+ // Remove temporary files.
+ for (list<t_msg>::iterator it = messages.begin(); it != messages.end(); ++it) {
+ // Temporary files are created for incoming messages only.
+ if (it->has_attachment && it->direction == MSG_DIR_IN) {
+ // Defensive check to make sure we are deleting tmp files only.
+ if (sys_config->is_tmpfile(it->attachment_filename)) {
+ log_file->write_header("t_msg_session::~t_msg_session");
+ log_file->write_raw("Remove tmp file ");
+ log_file->write_raw(it->attachment_filename);
+ log_file->write_endl();
+ log_file->write_footer();
+
+ unlink(it->attachment_filename.c_str());
+ }
+ }
+ }
+}
+
+t_user *t_msg_session::get_user(void) const {
+ return user_config;
+}
+
+t_display_url t_msg_session::get_remote_party(void) const {
+ return remote_party;
+}
+
+t_composing_state t_msg_session::get_remote_composing_state(void) const {
+ return remote_composing_state;
+}
+
+void t_msg_session::set_user(t_user *u) {
+ user_config = u;
+}
+
+void t_msg_session::set_remote_party(const t_display_url &du) {
+ remote_party = du;
+}
+
+void t_msg_session::set_send_composing_state(bool enable) {
+ send_composing_state = enable;
+}
+
+t_msg t_msg_session::get_last_message(void) {
+ new_message_added = false;
+ if (messages.empty()) {
+ throw empty_list_exception();
+ }
+ return messages.back();
+}
+
+bool t_msg_session::is_new_message_added(void) const {
+ return new_message_added;
+}
+
+void t_msg_session::set_display_if_empty(const string &display) {
+ if (remote_party.display.empty()) {
+ remote_party.display = display;
+ }
+}
+
+const list<t_msg> &t_msg_session::get_messages(void) const {
+ return messages;
+}
+
+void t_msg_session::recv_msg(const t_msg &msg) {
+ // RFC 3994 3.3
+ // The composing state of the remote party transitions to idle
+ // when a message is received.
+ remote_composing_state = COMPOSING_STATE_IDLE;
+ remote_idle_timeout = 0;
+
+ messages.push_back(msg);
+ new_message_added = true;
+ notify();
+}
+
+void t_msg_session::send_msg(const string &message, t_text_format format) {
+ // RFC 3994 3.2
+ // If a content message is sent before the idle threshold expires, no
+ // "idle" state indication is needed.
+ // The local state is set to idle without sending an indication to the
+ // remote party.
+ local_composing_state = COMPOSING_STATE_IDLE;
+ local_idle_timeout = 0;
+ local_refresh_timeout = 0;
+
+ t_msg msg(message, im::MSG_DIR_OUT, format);
+ messages.push_back(msg);
+ new_message_added = true;
+
+ bool ret = phone->pub_send_message(user_config, remote_party.url, remote_party.display, msg);
+
+ if (ret) {
+ msg_in_flight = true;
+ } else {
+ set_error(TRANSLATE("Failed to send message."));
+ }
+
+ notify();
+}
+
+void t_msg_session::send_file(const string &filename, const t_media &media, const string &subject) {
+ // RFC 3994 3.2
+ // If a content message is sent before the idle threshold expires, no
+ // "idle" state indication is needed.
+ // The local state is set to idle without sending an indication to the
+ // remote party.
+ local_composing_state = COMPOSING_STATE_IDLE;
+ local_idle_timeout = 0;
+ local_refresh_timeout = 0;
+
+ t_msg msg;
+ msg.set_attachment(filename, media, strip_path_from_filename(filename));
+ msg.subject = subject;
+ msg.direction = MSG_DIR_OUT;
+ messages.push_back(msg);
+ new_message_added = true;
+
+ bool ret = phone->pub_send_message(user_config, remote_party.url, remote_party.display, msg);
+
+ if (ret) {
+ msg_in_flight = true;
+ notify();
+ } else {
+ // Notify user interface about the sent message before
+ // setting the error.
+ notify();
+
+ set_error(TRANSLATE("Failed to send message."));
+ }
+}
+
+void t_msg_session::set_error(const string &message) {
+ error_msg = message;
+ error_recvd = true;
+ notify();
+}
+
+bool t_msg_session::error_received(void) const {
+ return error_recvd;
+}
+
+string t_msg_session::take_error(void) {
+ if (!error_recvd) return "";
+ error_recvd = false;
+ return error_msg;
+}
+
+void t_msg_session::set_delivery_notification(const string &notification) {
+ delivery_notification = notification;
+ delivery_notification_recvd = true;
+ notify();
+}
+
+bool t_msg_session::delivery_notification_received(void) const {
+ return delivery_notification_recvd;
+}
+
+string t_msg_session::take_delivery_notification(void) {
+ if (!delivery_notification_recvd) return "";
+ delivery_notification_recvd = false;
+ return delivery_notification;
+}
+
+bool t_msg_session::match(t_user *user, t_url _remote_party) {
+ return user == user_config && _remote_party == remote_party.url;
+}
+
+void t_msg_session::set_msg_in_flight(bool in_flight) {
+ msg_in_flight = in_flight;
+ notify();
+}
+
+bool t_msg_session::is_msg_in_flight(void) const {
+ return msg_in_flight;
+}
+
+void t_msg_session::set_local_composing_state(t_composing_state state) {
+ if (!remote_party.is_valid()) {
+ // The session is not yet established
+ return;
+ }
+
+ switch (local_composing_state) {
+ case COMPOSING_STATE_IDLE:
+ switch (state) {
+ case COMPOSING_STATE_IDLE:
+ break;
+ case COMPOSING_STATE_ACTIVE:
+ local_composing_state = state;
+ local_idle_timeout = COMPOSING_LOCAL_IDLE_TIMEOUT;
+ local_refresh_timeout = COMPOSING_LOCAL_REFRESH_TIMEOUT - 10;
+
+ if (send_composing_state) {
+ (void)phone->pub_send_im_iscomposing(
+ user_config, remote_party.url,
+ remote_party.display,
+ IM_ISCOMPOSING_STATE_ACTIVE,
+ COMPOSING_LOCAL_REFRESH_TIMEOUT);
+ }
+
+ break;
+ default:
+ assert(false);
+ }
+
+ break;
+ case COMPOSING_STATE_ACTIVE:
+ switch (state) {
+ case COMPOSING_STATE_IDLE:
+ local_composing_state = state;
+ local_idle_timeout = 0;
+ local_refresh_timeout = 0;
+
+ if (send_composing_state) {
+ (void)phone->pub_send_im_iscomposing(
+ user_config, remote_party.url,
+ remote_party.display,
+ IM_ISCOMPOSING_STATE_IDLE,
+ COMPOSING_LOCAL_REFRESH_TIMEOUT);
+ }
+
+ break;
+ case COMPOSING_STATE_ACTIVE:
+ local_idle_timeout = COMPOSING_LOCAL_IDLE_TIMEOUT;
+ break;
+ default:
+ assert(false);
+ }
+
+ break;
+ default:
+ assert(false);
+ }
+}
+
+void t_msg_session::set_remote_composing_state(t_composing_state state, time_t idle_timeout) {
+ switch (remote_composing_state) {
+ case COMPOSING_STATE_IDLE:
+ switch (state) {
+ case COMPOSING_STATE_IDLE:
+ break;
+ case COMPOSING_STATE_ACTIVE:
+ remote_composing_state = state;
+ remote_idle_timeout = idle_timeout;
+ notify();
+
+ break;
+ default:
+ assert(false);
+ }
+
+ break;
+ case COMPOSING_STATE_ACTIVE:
+ switch (state) {
+ case COMPOSING_STATE_IDLE:
+ remote_composing_state = state;
+ remote_idle_timeout = 0;
+ notify();
+
+ break;
+ case COMPOSING_STATE_ACTIVE:
+ remote_idle_timeout = idle_timeout;
+ break;
+ }
+
+ break;
+ default:
+ assert(false);
+ }
+}
+
+void t_msg_session::dec_local_composing_timeout(void) {
+ if (local_composing_state == COMPOSING_STATE_IDLE) return;
+
+ local_idle_timeout--;
+ if (local_idle_timeout == 0) {
+ set_local_composing_state(COMPOSING_STATE_IDLE);
+ } else {
+ local_refresh_timeout--;
+ if (local_refresh_timeout == 0) {
+ local_refresh_timeout = COMPOSING_LOCAL_REFRESH_TIMEOUT - 10;
+
+ if (send_composing_state) {
+ (void)phone->pub_send_im_iscomposing(
+ user_config, remote_party.url,
+ remote_party.display,
+ IM_ISCOMPOSING_STATE_ACTIVE,
+ COMPOSING_LOCAL_REFRESH_TIMEOUT);
+ }
+ }
+ }
+}
+
+void t_msg_session::dec_remote_composing_timeout(void) {
+ if (remote_composing_state == COMPOSING_STATE_IDLE) return;
+
+ remote_idle_timeout--;
+ if (remote_idle_timeout == 0) {
+ set_remote_composing_state(COMPOSING_STATE_IDLE);
+ }
+}