Пример #1
0
static int negchan_middle(aim_session_t *sess, aim_frame_t *fr)
{
	aim_tlvlist_t *tlvlist;
	char *msg = NULL;
	fu16_t code = 0;
	aim_rxcallback_t userfunc;
	int ret = 1;

	if (aim_bstream_empty(&fr->data) == 0) {
		/* XXX should do something with this */
		return 1;
	}

	/* Used only by the older login protocol */
	/* XXX remove this special case? */
	if (fr->conn->type == AIM_CONN_TYPE_AUTH)
		return consumenonsnac(sess, fr, 0x0017, 0x0003);

	tlvlist = aim_tlvlist_read(&fr->data);

	if (aim_tlv_gettlv(tlvlist, 0x0009, 1))
		code = aim_tlv_get16(tlvlist, 0x0009, 1);

	if (aim_tlv_gettlv(tlvlist, 0x000b, 1))
		msg = aim_tlv_getstr(tlvlist, 0x000b, 1);

	if ((userfunc = aim_callhandler(sess, fr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR)))
		ret = userfunc(sess, fr, code, msg);

	aim_tlvlist_free(&tlvlist);

	free(msg);

	return ret;
}
Пример #2
0
/*
 * aim_rxdispatch()
 *
 * Basically, heres what this should do:
 *   1) Determine correct packet handler for this packet
 *   2) Mark the packet handled (so it can be dequeued in purge_queue())
 *   3) Send the packet to the packet handler
 *   4) Go to next packet in the queue and start over
 *   5) When done, run purge_queue() to purge handled commands
 *
 * TODO: Clean up.
 * TODO: More support for mid-level handlers.
 * TODO: Allow for NULL handlers.
 *
 */
faim_export void aim_rxdispatch(aim_session_t *sess)
{
	int i;
	aim_frame_t *cur;

	for (cur = sess->queue_incoming, i = 0; cur; cur = cur->next, i++) {

		/*
		 * XXX: This is still fairly ugly.
		 */

		if (cur->handled)
			continue;

		if (cur->hdrtype == AIM_FRAMETYPE_FLAP) {
			if (cur->hdr.flap.channel == 0x01) {
				cur->handled = aim_callhandler_noparam(sess, cur->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, cur); /* XXX use consumenonsnac */
				continue;

			} else if (cur->hdr.flap.channel == 0x02) {
				if ((cur->handled = consumesnac(sess, cur)))
					continue;

			} else if (cur->hdr.flap.channel == 0x04) {
				cur->handled = negchan_middle(sess, cur);
				continue;

			} else if (cur->hdr.flap.channel == 0x05) {

			}

		} else if (cur->hdrtype == AIM_FRAMETYPE_OFT) {
			if (cur->conn->type == AIM_CONN_TYPE_RENDEZVOUS) {
				aim_rxdispatch_rendezvous(sess, cur);
				cur->handled = 1;
				continue;

			} else if (cur->conn->type == AIM_CONN_TYPE_LISTENER) {
				/* not possible */
				faimdprintf(sess, 0, "rxdispatch called on LISTENER connection!\n");
				cur->handled = 1;
				continue;
			}
		}

		if (!cur->handled) {
			consumenonsnac(sess, cur, 0xffff, 0xffff); /* last chance! */
			cur->handled = 1;
		}
	}

	/* 
	 * This doesn't have to be called here.  It could easily be done
	 * by a separate thread or something. It's an administrative operation,
	 * and can take a while. Though the less you call it the less memory
	 * you'll have :)
	 */
	aim_purge_rxqueue(sess);

	return;
}
Пример #3
0
/*
 * aim_rxdispatch()
 *
 * Basically, heres what this should do:
 *   1) Determine correct packet handler for this packet
 *   2) Mark the packet handled (so it can be dequeued in purge_queue())
 *   3) Send the packet to the packet handler
 *   4) Go to next packet in the queue and start over
 *   5) When done, run purge_queue() to purge handled commands
 *
 * TODO: Clean up.
 * TODO: More support for mid-level handlers.
 * TODO: Allow for NULL handlers.
 *
 */
faim_export void aim_rxdispatch(aim_session_t *sess)
{
	int i;
	aim_frame_t *cur;

	for (cur = sess->queue_incoming, i = 0; cur; cur = cur->next, i++) {

		/*
		 * XXX: This is still fairly ugly.
		 */

		if (cur->handled)
			continue;

		/*
		 * This is a debugging/sanity check only and probably 
		 * could/should be removed for stable code.
		 */
		if (((cur->hdrtype == AIM_FRAMETYPE_OFT) && 
		   (cur->conn->type != AIM_CONN_TYPE_RENDEZVOUS)) || 
		  ((cur->hdrtype == AIM_FRAMETYPE_FLAP) && 
		   (cur->conn->type == AIM_CONN_TYPE_RENDEZVOUS))) {
			faimdprintf(sess, 0, "rxhandlers: incompatible frame type %d on connection type 0x%04x\n", cur->hdrtype, cur->conn->type);
			cur->handled = 1;
			continue;
		}

		if (cur->conn->type == AIM_CONN_TYPE_RENDEZVOUS) {
			if (cur->hdrtype != AIM_FRAMETYPE_OFT) {
				faimdprintf(sess, 0, "internal error: non-OFT frames on OFT connection\n");
				cur->handled = 1; /* get rid of it */
			} else {
				/* XXX: implement this */
				faimdprintf(sess, 0, "faim: OFT frame!\n");
				cur->handled = 1; /* get rid of it */
			}
			continue;
		}

		if (cur->conn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
			/* not possible */
			faimdprintf(sess, 0, "rxdispatch called on RENDEZVOUS_OUT connection!\n");
			cur->handled = 1;
			continue;
		}

		if (cur->hdr.flap.type == 0x01) {
			
			cur->handled = aim_callhandler_noparam(sess, cur->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, cur); /* XXX use consumenonsnac */
			
			continue;
			
		} else if (cur->hdr.flap.type == 0x02) {

			if ((cur->handled = consumesnac(sess, cur)))
				continue;

		} else if (cur->hdr.flap.type == 0x04) {

			cur->handled = negchan_middle(sess, cur);
			continue;

		} else if (cur->hdr.flap.type == 0x05)
			;
		
		if (!cur->handled) {
			consumenonsnac(sess, cur, 0xffff, 0xffff); /* last chance! */
			cur->handled = 1;
		}
	}

	/* 
	 * This doesn't have to be called here.  It could easily be done
	 * by a seperate thread or something. It's an administrative operation,
	 * and can take a while. Though the less you call it the less memory
	 * you'll have :)
	 */
	aim_purge_rxqueue(sess);

	return;
}