Пример #1
0
void sipe_core_user_feedback_typing(struct sipe_core_public *sipe_public,
				    const gchar *to,
				    gboolean typing)
{
	struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE;
	struct sip_session *session = sipe_session_find_im(sipe_private, to);
	struct sip_dialog *dialog = sipe_dialog_find(session, to);

	/* only enable this debug output while testing
	SIPE_DEBUG_INFO("sipe_core_user_feedback_typing session %p (%s) dialog %p (%s) established %s",
			session, session ? session->callid : "N/A",
			dialog, dialog ? dialog->callid : "N/A",
			(dialog && dialog->is_established) ? "YES" : "NO"); */

	if (session && dialog && dialog->is_established) {
		gchar *body = g_strdup_printf("<?xml version=\"1.0\"?>"
					      "<KeyboardActivity>"
					      " <status status=\"%s\" />"
					      "</KeyboardActivity>",
					      typing ? "type" : "idle");
		sip_transport_info(sipe_private,
				   "Content-Type: application/xml\r\n",
				   body,
				   dialog,
				   process_info_typing_response);
		g_free(body);
	}
}
Пример #2
0
struct sip_session *
sipe_session_find_or_add_im(struct sipe_account_data *sip,
			    const gchar *who)
{
	struct sip_session *session = sipe_session_find_im(sip, who);
	if (!session) {
		purple_debug_info("sipe", "sipe_session_find_or_add_im: new session for %s\n", who);
		session = g_new0(struct sip_session, 1);
		session->is_multiparty = FALSE;
		session->with = g_strdup(who);
		session->unconfirmed_messages = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
		sip->sessions = g_slist_append(sip->sessions, session);
	}
Пример #3
0
static gboolean process_info_typing_response(struct sipe_core_private *sipe_private,
					     struct sipmsg *msg,
					     SIPE_UNUSED_PARAMETER struct transaction *trans)
{
	/* Indicates dangling IM session which needs to be dropped */
	if (msg->response == 408 || /* Request timeout */
	    msg->response == 480 || /* Temporarily Unavailable */
	    msg->response == 481) { /* Call/Transaction Does Not Exist */
		gchar *with = parse_from(sipmsg_find_header(msg, "To"));
		struct sip_session *session = sipe_session_find_im(sipe_private, with);
		struct sip_dialog *dialog = sipe_dialog_find(session, with);
		if (dialog)
			sipe_im_cancel_dangling(sipe_private, session, dialog, with,
						sipe_im_cancel_unconfirmed);
		g_free(with);
	}	
	return(TRUE);
}
Пример #4
0
/** Invite counterparty to join conference callback */
static gboolean
process_invite_conf_response(struct sipe_core_private *sipe_private,
			     struct sipmsg *msg,
			     SIPE_UNUSED_PARAMETER struct transaction *trans)
{
	struct sip_dialog *dialog = g_new0(struct sip_dialog, 1);

	dialog->callid = g_strdup(sipmsg_find_header(msg, "Call-ID"));
	dialog->cseq = sipmsg_parse_cseq(msg);
	dialog->with = parse_from(sipmsg_find_header(msg, "To"));
	sipe_dialog_parse(dialog, msg, TRUE);

	if (msg->response >= 200) {
		/* send ACK to counterparty */
		dialog->cseq--;
		sip_transport_ack(sipe_private, dialog);
		dialog->outgoing_invite = NULL;
		dialog->is_established = TRUE;
	}

	if (msg->response >= 400) {
		SIPE_DEBUG_INFO("process_invite_conf_response: INVITE response is not 200. Failed to invite %s.", dialog->with);
		/* @TODO notify user of failure to invite counterparty */
		sipe_dialog_free(dialog);
		return FALSE;
	}

	if (msg->response >= 200) {
		struct sip_session *session = sipe_session_find_im(sipe_private, dialog->with);
		struct sip_dialog *im_dialog = sipe_dialog_find(session, dialog->with);

		/* close IM session to counterparty */
		if (im_dialog) {
			sip_transport_bye(sipe_private, im_dialog);
			sipe_dialog_remove(session, dialog->with);
		}
	}

	sipe_dialog_free(dialog);
	return TRUE;
}