static void
release_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
{
	MsnCmdProc *cmdproc;
	MsnTransaction *trans;
	char *payload;
	gsize payload_len;
	char flag;

	g_return_if_fail(swboard != NULL);
	g_return_if_fail(msg     != NULL);

	cmdproc = swboard->cmdproc;

	payload = msn_message_gen_payload(msg, &payload_len);

	if (purple_debug_is_verbose()) {
		purple_debug_info("msn", "SB length:{%" G_GSIZE_FORMAT "}\n", payload_len);
		msn_message_show_readable(msg, "SB SEND", FALSE);
	}

	flag = msn_message_get_flag(msg);
	trans = msn_transaction_new(cmdproc, "MSG", "%c %" G_GSIZE_FORMAT,
								flag, payload_len);

	/* Data for callbacks */
	msn_transaction_set_data(trans, msg);

	if (flag != 'U') {
		if (msg->type == MSN_MSG_TEXT)
		{
			msg->ack_ref = TRUE;
			msn_message_ref(msg);
			swboard->ack_list = g_list_append(swboard->ack_list, msg);
			msn_transaction_set_timeout_cb(trans, msg_timeout);
		}
		else if (msg->type == MSN_MSG_SLP)
		{
			msg->ack_ref = TRUE;
			msn_message_ref(msg);
			swboard->ack_list = g_list_append(swboard->ack_list, msg);
			msn_transaction_set_timeout_cb(trans, msg_timeout);
#if 0
			if (msg->ack_cb != NULL)
			{
				msn_transaction_add_cb(trans, "ACK", msg_ack);
				msn_transaction_add_cb(trans, "NAK", msg_nak);
			}
#endif
		}
	}

	trans->payload = payload;
	trans->payload_len = payload_len;

	msg->trans = trans;

	msn_cmdproc_send_trans(cmdproc, trans);
}
Exemple #2
0
static void
release_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
{
	MsnCmdProc *cmdproc;
	MsnTransaction *trans;
	char *payload;
	gsize payload_len;

	g_return_if_fail(swboard != NULL);
	g_return_if_fail(msg     != NULL);

	cmdproc = swboard->cmdproc;

	payload = msn_message_gen_payload(msg, &payload_len);

#ifdef MSN_DEBUG_SB
	msn_message_show_readable(msg, "SB SEND", FALSE);
#endif

	trans = msn_transaction_new(cmdproc, "MSG", "%c %d",
								msn_message_get_flag(msg), payload_len);

	/* Data for callbacks */
	msn_transaction_set_data(trans, msg);

	if (msg->type == MSN_MSG_TEXT)
	{
		msg->ack_ref = TRUE;
		msn_message_ref(msg);
		swboard->ack_list = g_list_append(swboard->ack_list, msg);
		msn_transaction_set_timeout_cb(trans, msg_timeout);
	}
	else if (msg->type == MSN_MSG_SLP)
	{
		msg->ack_ref = TRUE;
		msn_message_ref(msg);
		swboard->ack_list = g_list_append(swboard->ack_list, msg);
		msn_transaction_set_timeout_cb(trans, msg_timeout);
#if 0
		if (msg->ack_cb != NULL)
		{
			msn_transaction_add_cb(trans, "ACK", msg_ack);
			msn_transaction_add_cb(trans, "NAK", msg_nak);
		}
#endif
	}

	trans->payload = payload;
	trans->payload_len = payload_len;

	msg->trans = trans;

	msn_cmdproc_send_trans(cmdproc, trans);
}
static void
queue_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
{
	g_return_if_fail(swboard != NULL);
	g_return_if_fail(msg     != NULL);

	purple_debug_info("msn", "Appending message to queue.\n");

	g_queue_push_tail(swboard->msg_queue, msg);

	msn_message_ref(msg);
}
Exemple #4
0
void
msn_slp_session_send_msg(MsnSlpSession *slpsession, MsnMessage *msg)
{
	g_return_if_fail(slpsession != NULL);
	g_return_if_fail(msg != NULL);
	g_return_if_fail(msg->msnslp_message);
	g_return_if_fail(slpsession->outgoing_msg == NULL);

	msg->msnslp_header.session_id = slpsession->session_id;

	slpsession->outgoing_msg = msn_message_ref(msg);

	if (slpsession->base_id == 0)
	{
		slpsession->base_id = rand() % 0x0FFFFFF0 + 4;
		slpsession->prev_msg_id = slpsession->base_id;
	}
	else if (slpsession->offset == 0)
		slpsession->prev_msg_id = ++slpsession->base_id;

	msg->msnslp_header.id = slpsession->prev_msg_id;
//	msg->msnslp_header.ack_session_id = rand() % 0xFFFFFF00;
	msg->msnslp_header.ack_session_id = 0x1407C7DE;

	msn_message_set_charset(msg, NULL);

	if (msg->msnslp_header.session_id != 0)
		msg->msnslp_footer.app_id = 1;

	if (msg->bin_content)
	{
		const void *temp;

		temp = msn_message_get_bin_data(msg, &slpsession->orig_len);

		slpsession->orig_body = g_memdup(temp, slpsession->orig_len);
	}
	else
	{
		slpsession->orig_body = g_strdup(msn_message_get_body(msg));
		slpsession->orig_len  = strlen(slpsession->orig_body);
	}

	msg->msnslp_header.total_size_1 = slpsession->orig_len;

	send_msg_part(slpsession, msg);
}
Exemple #5
0
MsnMessage *
msn_message_new(MsnMsgType type)
{
	MsnMessage *msg;

	msg = g_new0(MsnMessage, 1);
	msg->type = type;

	if (purple_debug_is_verbose())
		purple_debug_info("msn", "message new (%p)(%d)\n", msg, type);

	msg->header_table = g_hash_table_new_full(g_str_hash, g_str_equal,
											g_free, g_free);

	msn_message_ref(msg);

	return msg;
}
Exemple #6
0
MsnMessage *
msn_message_new(MsnMsgType type)
{
	MsnMessage *msg;

	msg = g_new0(MsnMessage, 1);
	msg->type = type;

#ifdef MSN_DEBUG_MSG
	purple_debug_info("msn", "message new (%p)(%d)\n", msg, type);
#endif

	msg->attr_table = g_hash_table_new_full(g_str_hash, g_str_equal,
											g_free, g_free);

	msn_message_ref(msg);

	return msg;
}
Exemple #7
0
MsnMessage *
msn_message_new(MsnMsgType type)
{
    MsnMessage *msg;

    msg = g_new0(MsnMessage, 1);
    msg->type = type;

#ifdef PECAN_DEBUG_MSG
    pn_log ("msg=%p,type=%d", msg, type);
#endif

    msg->attr_table = g_hash_table_new_full(g_str_hash, g_str_equal,
                                            g_free, g_free);

    msn_message_ref(msg);

    return msg;
}
Exemple #8
0
/* We have received the message ack */
static void
msg_ack(MsnMessage *msg, void *data)
{
	MsnSlpMessage *slpmsg;
	long long real_size;

	slpmsg = data;

	real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size;

	slpmsg->offset += msg->msnslp_header.length;

	slpmsg->msgs = g_list_remove(slpmsg->msgs, msg);

	if (slpmsg->offset < real_size)
	{
		if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED)
		{
			slpmsg->slpcall->xfer_msg = slpmsg;
			msn_message_ref(msg);
			purple_xfer_prpl_ready(slpmsg->slpcall->xfer);
		}
		else
			msn_slplink_send_msgpart(slpmsg->slplink, slpmsg);
	}
	else
	{
		/* The whole message has been sent */
		if (slpmsg->flags == 0x20 ||
		    slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030)
		{
			if (slpmsg->slpcall != NULL)
			{
				if (slpmsg->slpcall->cb)
					slpmsg->slpcall->cb(slpmsg->slpcall,
						NULL, 0);
			}
		}
	}

	msn_message_unref(msg);
}
Exemple #9
0
void
msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
{
	MsnMessage *msg;
	long long real_size;
	size_t len = 0;

	/* Maybe we will want to create a new msg for this slpmsg instead of
	 * reusing the same one all the time. */
	msg = slpmsg->msg;

	real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size;

	if (slpmsg->offset < real_size)
	{
		if (slpmsg->slpcall && slpmsg->slpcall->xfer && purple_xfer_get_type(slpmsg->slpcall->xfer) == PURPLE_XFER_SEND &&
				purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED)
		{
			len = MIN(1202, slpmsg->slpcall->u.outgoing.len);
			msn_message_set_bin_data(msg, slpmsg->slpcall->u.outgoing.data, len);
		}
		else
		{
			len = slpmsg->size - slpmsg->offset;

			if (len > 1202)
				len = 1202;

			msn_message_set_bin_data(msg, slpmsg->buffer + slpmsg->offset, len);
		}

		msg->msnslp_header.offset = slpmsg->offset;
		msg->msnslp_header.length = len;
	}

	if (purple_debug_is_verbose())
		msn_message_show_readable(msg, slpmsg->info, slpmsg->text_body);

#ifdef MSN_DEBUG_SLP_FILES
	debug_msg_to_file(msg, TRUE);
#endif

	slpmsg->msgs =
		g_list_append(slpmsg->msgs, msn_message_ref(msg));
	msn_slplink_send_msg(slplink, msg);

	if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 ||
	     slpmsg->flags == 0x1000030) &&
		(slpmsg->slpcall != NULL))
	{
		slpmsg->slpcall->progress = TRUE;

		if (slpmsg->slpcall->progress_cb != NULL)
		{
			slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size,
										 len, slpmsg->offset);
		}
	}

	/* slpmsg->offset += len; */
}
Exemple #10
0
void
msn_cmdproc_process_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
{
	MsnMsgTypeCb cb;
	const char *messageId = NULL;

	/* Multi-part messages */
	if ((messageId = msn_message_get_attr(msg, "Message-ID")) != NULL) {
		const char *chunk_text = msn_message_get_attr(msg, "Chunks");
		guint chunk;
		if (chunk_text != NULL) {
			chunk = strtol(chunk_text, NULL, 10);
			/* 1024 chunks of ~1300 bytes is ~1MB, which seems OK to prevent 
			   some random client causing pidgin to hog a ton of memory.
			   Probably should figure out the maximum that the official client
			   actually supports, though. */
			if (chunk > 0 && chunk < 1024) {
				msg->total_chunks = chunk;
				msg->received_chunks = 1;
				g_hash_table_insert(cmdproc->multiparts, (gpointer)messageId, msn_message_ref(msg));
				purple_debug_info("msn", "Received chunked message, messageId: '%s', total chunks: %d\n",
				                  messageId, chunk);
			} else {
				purple_debug_error("msn", "MessageId '%s' has too many chunks: %d\n", messageId, chunk);
			}
			return;
		} else {
			chunk_text = msn_message_get_attr(msg, "Chunk");
			if (chunk_text != NULL) {
				MsnMessage *first = g_hash_table_lookup(cmdproc->multiparts, messageId);
				chunk = strtol(chunk_text, NULL, 10);
				if (first == NULL) {
					purple_debug_error("msn",
					                   "Unable to find first chunk of messageId '%s' to correspond with chunk %d.\n",
					                   messageId, chunk+1);
				} else if (first->received_chunks == chunk) {
					/* Chunk is from 1 to total-1 (doesn't count first one) */
					purple_debug_info("msn", "Received chunk %d of %d, messageId: '%s'\n",
					                  chunk+1, first->total_chunks, messageId);
					first->body = g_realloc(first->body, first->body_len + msg->body_len);
					memcpy(first->body + first->body_len, msg->body, msg->body_len);
					first->body_len += msg->body_len;
					first->received_chunks++;
					if (first->received_chunks != first->total_chunks)
						return;
					else
						/* We're done! Send it along... The caller takes care of
						   freeing the old one. */
						msg = first;
				} else {
					/* TODO: Can you legitimately receive chunks out of order? */
					g_hash_table_remove(cmdproc->multiparts, messageId);
					return;
				}
			} else {
				purple_debug_error("msn", "Received MessageId '%s' with no chunk number!\n", messageId);
			}
		}
	}

	if (msn_message_get_content_type(msg) == NULL)
	{
		purple_debug_misc("msn", "failed to find message content\n");
		return;
	}

	cb = g_hash_table_lookup(cmdproc->cbs_table->msgs,
							 msn_message_get_content_type(msg));

	if (cb != NULL)
		cb(cmdproc, msg);
	else
		purple_debug_warning("msn", "Unhandled content-type '%s'\n",
						   msn_message_get_content_type(msg));

	if (messageId != NULL)
		g_hash_table_remove(cmdproc->multiparts, messageId);
}