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; }
/* * 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; }
/* * 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; }