comparison src/protocols/oscar/ft.c @ 4870:773135edda4a

[gaim-migrate @ 5200] Added 3-stage typing notification for oscar direct connect (incoming and outgoing). Previously Gaim only had "typing" and "no text entered." I added support for "text typed." Made Gaim correctly recognize and send the auto-response flag for direct connections. So messages will probably show up as "AUTO-REPLY" for you and your amigo. Have gaim save your blist after recieving someone's icon, which is a bugfix from my code from last night, I think. Fixed a memleak in icon.c thanks to Nathan Walp. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 23 Mar 2003 07:38:55 +0000
parents edfe778868e2
children 26837f462a66
comparison
equal deleted inserted replaced
4869:e6c7d67c1f3a 4870:773135edda4a
304 /** 304 /**
305 * Send client-to-client typing notification over an established direct connection. 305 * Send client-to-client typing notification over an established direct connection.
306 * 306 *
307 * @param sess The session. 307 * @param sess The session.
308 * @param conn The already-connected ODC connection. 308 * @param conn The already-connected ODC connection.
309 * @param typing If true, notify user has started typing; if false, notify user has stopped. 309 * @param typing If 0x0002, sends a "typing" message, 0x0001 sends "typed," and
310 * 0x0000 sends "stopped."
310 * @return Return 0 if no errors, otherwise return the error number. 311 * @return Return 0 if no errors, otherwise return the error number.
311 */ 312 */
312 faim_export int aim_odc_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing) 313 faim_export int aim_odc_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing)
313 { 314 {
314 struct aim_odc_intdata *intdata = (struct aim_odc_intdata *)conn->internal; 315 struct aim_odc_intdata *intdata = (struct aim_odc_intdata *)conn->internal;
318 int hdrlen = 0x44; 319 int hdrlen = 0x44;
319 320
320 if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS)) 321 if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS))
321 return -EINVAL; 322 return -EINVAL;
322 323
323 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x01, 0))) 324 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0001, 0)))
324 return -ENOMEM; 325 return -ENOMEM;
325 memcpy(fr->hdr.rend.magic, "ODC2", 4); 326 memcpy(fr->hdr.rend.magic, "ODC2", 4);
326 fr->hdr.rend.hdrlen = hdrlen; 327 fr->hdr.rend.hdrlen = hdrlen;
327 328
328 if (!(hdr = calloc(1, hdrlen))) { 329 if (!(hdr = calloc(1, hdrlen))) {
343 aimbs_put32(hdrbs, 0x00000000); 344 aimbs_put32(hdrbs, 0x00000000);
344 aimbs_put16(hdrbs, 0x0000); 345 aimbs_put16(hdrbs, 0x0000);
345 aimbs_put16(hdrbs, 0x0000); 346 aimbs_put16(hdrbs, 0x0000);
346 aimbs_put16(hdrbs, 0x0000); 347 aimbs_put16(hdrbs, 0x0000);
347 348
348 /* flags -- 0x000e for "started typing", 0x0002 for "stopped typing */ 349 if (typing == 0x0002)
349 aimbs_put16(hdrbs, ( typing ? 0x000e : 0x0002)); 350 aimbs_put16(hdrbs, 0x0002 | 0x0008);
351 else if (typing == 0x0001)
352 aimbs_put16(hdrbs, 0x0002 | 0x0004);
353 else
354 aimbs_put16(hdrbs, 0x0002);
350 355
351 aimbs_put16(hdrbs, 0x0000); 356 aimbs_put16(hdrbs, 0x0000);
352 aimbs_put16(hdrbs, 0x0000); 357 aimbs_put16(hdrbs, 0x0000);
353 aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn)); 358 aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn));
354 359
378 * @param sess The session. 383 * @param sess The session.
379 * @param conn The already-connected ODC connection. 384 * @param conn The already-connected ODC connection.
380 * @param msg Null-terminated string to send. 385 * @param msg Null-terminated string to send.
381 * @param len The length of the message to send, including binary data. 386 * @param len The length of the message to send, including binary data.
382 * @param encoding 0 for ascii, 2 for Unicode, 3 for ISO 8859-1. 387 * @param encoding 0 for ascii, 2 for Unicode, 3 for ISO 8859-1.
388 * @param isawaymsg 0 if this is not an auto-response, 1 if it is.
383 * @return Return 0 if no errors, otherwise return the error number. 389 * @return Return 0 if no errors, otherwise return the error number.
384 */ 390 */
385 faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding) 391 faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding, int isawaymsg)
386 { 392 {
387 aim_frame_t *fr; 393 aim_frame_t *fr;
388 aim_bstream_t *hdrbs; 394 aim_bstream_t *hdrbs;
389 struct aim_odc_intdata *intdata = (struct aim_odc_intdata *)conn->internal; 395 struct aim_odc_intdata *intdata = (struct aim_odc_intdata *)conn->internal;
390 int hdrlen = 0x44; 396 int hdrlen = 0x44;
417 aimbs_put32(hdrbs, len); 423 aimbs_put32(hdrbs, len);
418 aimbs_put16(hdrbs, encoding); 424 aimbs_put16(hdrbs, encoding);
419 aimbs_put16(hdrbs, 0x0000); 425 aimbs_put16(hdrbs, 0x0000);
420 aimbs_put16(hdrbs, 0x0000); 426 aimbs_put16(hdrbs, 0x0000);
421 427
422 /* flags -- 0x000e for "started typing", 0x0002 for "stopped typing, 0x0000 for message */ 428 /* flags - used for typing notification and to mark if this is an away message */
423 aimbs_put16(hdrbs, 0x0000); 429 aimbs_put16(hdrbs, 0x0000 | isawaymsg);
424 430
425 aimbs_put16(hdrbs, 0x0000); 431 aimbs_put16(hdrbs, 0x0000);
426 aimbs_put16(hdrbs, 0x0000); 432 aimbs_put16(hdrbs, 0x0000);
427 aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn)); 433 aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn));
428 434
622 * @return Return 0 if no errors, otherwise return the error number. 628 * @return Return 0 if no errors, otherwise return the error number.
623 */ 629 */
624 static int handlehdr_odc(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *frr, aim_bstream_t *bs) 630 static int handlehdr_odc(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *frr, aim_bstream_t *bs)
625 { 631 {
626 aim_frame_t fr; 632 aim_frame_t fr;
633 int ret = 0;
627 aim_rxcallback_t userfunc; 634 aim_rxcallback_t userfunc;
628 fu32_t payloadlength; 635 fu32_t payloadlength;
629 fu16_t flags, encoding; 636 fu16_t flags, encoding;
630 char *snptr = NULL; 637 char *snptr = NULL;
631 638
645 /* XXX - create an aimbs_getnullstr function? */ 652 /* XXX - create an aimbs_getnullstr function? */
646 snptr = aimbs_getstr(bs, MAXSNLEN); 653 snptr = aimbs_getstr(bs, MAXSNLEN);
647 654
648 faimdprintf(sess, 2, "faim: OFT frame: handlehdr_odc: %04x / %04x / %s\n", payloadlength, flags, snptr); 655 faimdprintf(sess, 2, "faim: OFT frame: handlehdr_odc: %04x / %04x / %s\n", payloadlength, flags, snptr);
649 656
650 if (flags & 0x0002) { 657 if (flags & 0x0008) {
651 int ret = 0; 658 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)))
652 659 ret = userfunc(sess, &fr, snptr, 2);
653 if (flags & 0x000c) { 660 } else if (flags & 0x0004) {
654 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING))) 661 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)))
655 ret = userfunc(sess, &fr, snptr, 1); 662 ret = userfunc(sess, &fr, snptr, 1);
656 return ret; 663 } else {
657 }
658
659 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING))) 664 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)))
660 ret = userfunc(sess, &fr, snptr, 0); 665 ret = userfunc(sess, &fr, snptr, 0);
661 666 }
662 return ret; 667
663 668 if (payloadlength) {
664 } else if (((flags & 0x000f) == 0x0000) && payloadlength) { 669 char *msg;
665 char *msg, *msg2;
666 int ret = 0;
667 int recvd = 0; 670 int recvd = 0;
668 int i; 671 int i, isawaymsg;
672
673 isawaymsg = flags & 0x0001;
669 674
670 if (!(msg = calloc(1, payloadlength+1))) 675 if (!(msg = calloc(1, payloadlength+1)))
671 return -1; 676 return -ENOMEM;
672 msg2 = msg; 677
673
674 while (payloadlength - recvd) { 678 while (payloadlength - recvd) {
675 if (payloadlength - recvd >= 1024) 679 if (payloadlength - recvd >= 1024)
676 i = aim_recv(conn->fd, msg2, 1024); 680 i = aim_recv(conn->fd, &msg[recvd], 1024);
677 else 681 else
678 i = aim_recv(conn->fd, msg2, payloadlength - recvd); 682 i = aim_recv(conn->fd, &msg[recvd], payloadlength - recvd);
679 if (i <= 0) { 683 if (i <= 0) {
680 free(msg); 684 free(msg);
681 return -1; 685 return -1;
682 } 686 }
683 recvd = recvd + i; 687 recvd = recvd + i;
684 msg2 = msg2 + i;
685 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER))) 688 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER)))
686 userfunc(sess, &fr, snptr, (double)recvd / payloadlength); 689 ret = userfunc(sess, &fr, snptr, (double)recvd / payloadlength);
687 } 690 }
688 691
689 if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING)) ) 692 if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING)))
690 ret = userfunc(sess, &fr, snptr, msg, payloadlength, encoding); 693 ret = userfunc(sess, &fr, snptr, msg, payloadlength, encoding, isawaymsg);
691 694
692 free(msg); 695 free(msg);
693 696 }
694 return ret; 697
695 } 698 return ret;
696
697 return 0;
698 } 699 }
699 700
700 /** 701 /**
701 * Creates a listener socket so the other dude can connect to us. 702 * Creates a listener socket so the other dude can connect to us.
702 * 703 *