comparison mcabber/src/jabglue.c @ 990:35e7913affb7

Send events/chatstates notifications (JEP-22/JEP-85)
author Mikael Berthe <mikael@lilotux.net>
date Wed, 01 Nov 2006 00:57:56 +0100
parents 859ab76e5093
children ef10906691bb
comparison
equal deleted inserted replaced
989:859ab76e5093 990:35e7913affb7
479 xmlnode_put_attrib(event, "xmlns", NS_CHATSTATES); 479 xmlnode_put_attrib(event, "xmlns", NS_CHATSTATES);
480 if (jep85->support == CHATSTATES_SUPPORT_UNKNOWN) 480 if (jep85->support == CHATSTATES_SUPPORT_UNKNOWN)
481 jep85->support = CHATSTATES_SUPPORT_PROBED; 481 jep85->support = CHATSTATES_SUPPORT_PROBED;
482 else 482 else
483 which_jep = 1; 483 which_jep = 1;
484 jep85->last_state_sent = ROSTER_EVENT_ACTIVE;
484 } 485 }
485 #endif 486 #endif
486 #ifdef JEP0022 487 #ifdef JEP0022
487 /* JEP-22 488 /* JEP-22
488 * If the Contact supports JEP-0085, we do not use JEP-0022. 489 * If the Contact supports JEP-0085, we do not use JEP-0022.
489 * If not, we try to fall back to JEP-0022. 490 * If not, we try to fall back to JEP-0022.
490 */ 491 */
491 if (!which_jep) { 492 if (!which_jep) {
493 struct jep0022 *jep22 = NULL;
492 event = xmlnode_insert_tag(x, "x"); 494 event = xmlnode_insert_tag(x, "x");
493 xmlnode_put_attrib(event, "xmlns", NS_EVENT); 495 xmlnode_put_attrib(event, "xmlns", NS_EVENT);
494 xmlnode_insert_tag(event, "composing"); 496 xmlnode_insert_tag(event, "composing");
495 497
498 if (sl_buddy)
499 jep22 = buddy_resource_jep22(sl_buddy->data, rname);
500 if (jep22)
501 jep22->last_state_sent = ROSTER_EVENT_ACTIVE;
502
496 // An id is mandatory when using JEP-0022. 503 // An id is mandatory when using JEP-0022.
497 if (!msgid && (text || subject)) { 504 if (!msgid && (text || subject)) {
498 struct jep0022 *jep22;
499 msgid = new_msgid(); 505 msgid = new_msgid();
500 // Let's update last_msgid_sent 506 // Let's update last_msgid_sent
501 // (We do not update it when the msgid is provided by the caller, 507 // (We do not update it when the msgid is provided by the caller,
502 // because this is probably a special message...) 508 // because this is probably a special message...)
503 if (sl_buddy)
504 jep22 = buddy_resource_jep22(sl_buddy->data, rname);
505 if (jep22) { 509 if (jep22) {
506 g_free(jep22->last_msgid_sent); 510 g_free(jep22->last_msgid_sent);
507 jep22->last_msgid_sent = g_strdup(msgid); 511 jep22->last_msgid_sent = g_strdup(msgid);
508 } 512 }
509 } 513 }
516 xmlnode_free(x); 520 xmlnode_free(x);
517 521
518 jb_reset_keepalive(); 522 jb_reset_keepalive();
519 } 523 }
520 524
525
526 #ifdef JEP0085
527 // jb_send_jep85_chatstate()
528 // Send a JEP-85 chatstate.
529 static void jb_send_jep85_chatstate(const char *jid, guint state)
530 {
531 xmlnode x;
532 xmlnode event;
533 char *rname, *barejid;
534 GSList *sl_buddy;
535 const char *chattag;
536 struct jep0085 *jep85 = NULL;
537
538 if (!online) return;
539
540 rname = strchr(jid, JID_RESOURCE_SEPARATOR);
541 barejid = jidtodisp(jid);
542 sl_buddy = roster_find(barejid, jidsearch, ROSTER_TYPE_USER);
543 g_free(barejid);
544
545 // If we can get a resource name, we use it. Else we use NULL,
546 // which hopefully will give us the most likely resource.
547 if (rname)
548 rname++;
549 if (sl_buddy)
550 jep85 = buddy_resource_jep85(sl_buddy->data, rname);
551
552 if (!jep85 || (jep85->support != CHATSTATES_SUPPORT_OK))
553 return;
554
555 if (state == jep85->last_state_sent)
556 return;
557
558 if (state == ROSTER_EVENT_ACTIVE)
559 chattag = "active";
560 else if (state == ROSTER_EVENT_COMPOSING)
561 chattag = "composing";
562 else if (state == ROSTER_EVENT_PAUSED)
563 chattag = "paused";
564 else {
565 scr_LogPrint(LPRINT_LOGNORM, "Error: unsupported JEP-85 state (%d)", state);
566 return;
567 }
568
569 jep85->last_state_sent = state;
570
571 x = jutil_msgnew(TMSG_CHAT, (char*)jid, NULL, NULL);
572
573 event = xmlnode_insert_tag(x, chattag);
574 xmlnode_put_attrib(event, "xmlns", NS_CHATSTATES);
575
576 jab_send(jc, x);
577 xmlnode_free(x);
578
579 jb_reset_keepalive();
580 }
581 #endif
582
521 #ifdef JEP0022 583 #ifdef JEP0022
522 // jb_send_jep22_event() 584 // jb_send_jep22_event()
523 // Send a JEP-22 message event (delivered, composing...). 585 // Send a JEP-22 message event (delivered, composing...).
524 void jb_send_jep22_event(const char *jid, guint type) 586 static void jb_send_jep22_event(const char *jid, guint type)
525 { 587 {
526 xmlnode x; 588 xmlnode x;
527 xmlnode event; 589 xmlnode event;
528 const char *msgid; 590 const char *msgid;
529 char *rname, *barejid; 591 char *rname, *barejid;
530 GSList *sl_buddy; 592 GSList *sl_buddy;
531 struct jep0022 *jep22 = NULL; 593 struct jep0022 *jep22 = NULL;
594 guint jep22_state;
532 595
533 if (!online) return; 596 if (!online) return;
534 597
535 rname = strchr(jid, JID_RESOURCE_SEPARATOR); 598 rname = strchr(jid, JID_RESOURCE_SEPARATOR);
536 barejid = jidtodisp(jid); 599 barejid = jidtodisp(jid);
542 if (rname) 605 if (rname)
543 rname++; 606 rname++;
544 if (sl_buddy) 607 if (sl_buddy)
545 jep22 = buddy_resource_jep22(sl_buddy->data, rname); 608 jep22 = buddy_resource_jep22(sl_buddy->data, rname);
546 609
547 if (jep22) 610 if (!jep22)
548 msgid = jep22->last_msgid_rcvd; 611 return; // XXX Maybe we could try harder (other resources?)
612
613 msgid = jep22->last_msgid_rcvd;
614
615 // For composing events (composing, active, inactive, paused...),
616 // JEP22 only has 2 states; we'll use composing and active.
617 if (type == ROSTER_EVENT_COMPOSING)
618 jep22_state = ROSTER_EVENT_COMPOSING;
619 else if (type == ROSTER_EVENT_ACTIVE ||
620 type == ROSTER_EVENT_PAUSED)
621 jep22_state = ROSTER_EVENT_ACTIVE;
622 else
623 jep22_state = 0; // ROSTER_EVENT_NONE
624
625 if (jep22_state) {
626 // Do not re-send a same event
627 if (jep22_state == jep22->last_state_sent)
628 return;
629 jep22->last_state_sent = jep22_state;
630 }
549 631
550 x = jutil_msgnew(TMSG_CHAT, (char*)jid, NULL, NULL); 632 x = jutil_msgnew(TMSG_CHAT, (char*)jid, NULL, NULL);
551 633
552 event = xmlnode_insert_tag(x, "x"); 634 event = xmlnode_insert_tag(x, "x");
553 xmlnode_put_attrib(event, "xmlns", NS_EVENT); 635 xmlnode_put_attrib(event, "xmlns", NS_EVENT);
554 if (type == ROSTER_EVENT_DELIVERED) 636 if (type == ROSTER_EVENT_DELIVERED)
555 xmlnode_insert_tag(event, "delivered"); 637 xmlnode_insert_tag(event, "delivered");
556 else if (type == ROSTER_EVENT_COMPOSING) 638 else if (type == ROSTER_EVENT_COMPOSING)
557 xmlnode_insert_tag(event, "composing"); 639 xmlnode_insert_tag(event, "composing");
558 xmlnode_put_attrib(event, "id", (msgid ? msgid : "")); 640 xmlnode_put_attrib(event, "id", msgid);
559 641
560 jab_send(jc, x); 642 jab_send(jc, x);
561 xmlnode_free(x); 643 xmlnode_free(x);
562 644
563 jb_reset_keepalive(); 645 jb_reset_keepalive();
646 }
647 #endif
648
649 #if defined JEP0022 || defined JEP0085
650 void jb_send_chatstate(gpointer buddy, guint chatstate)
651 {
652 const char *jid;
653 struct jep0085 *jep85 = NULL;
654 struct jep0022 *jep22 = NULL;
655
656 jid = buddy_getjid(buddy);
657 if (!jid) return;
658
659 #ifdef JEP0085
660 jep85 = buddy_resource_jep85(buddy, NULL);
661 if (jep85 && jep85->support == CHATSTATES_SUPPORT_OK) {
662 // FIXME: compare w/ last state sent...
663 jb_send_jep85_chatstate(jid, chatstate);
664 return;
665 }
666 #endif
667 #ifdef JEP0022
668 jep22 = buddy_resource_jep22(buddy, NULL);
669 if (jep22 && jep22->support == CHATSTATES_SUPPORT_OK) {
670 // FIXME: compare w/ last state sent...
671 jb_send_jep22_event(jid, chatstate);
672 }
673 #endif
564 } 674 }
565 #endif 675 #endif
566 676
567 // jb_subscr_send_auth(jid) 677 // jb_subscr_send_auth(jid)
568 // Allow jid to receive our presence updates 678 // Allow jid to receive our presence updates
1570 } 1680 }
1571 1681
1572 void handle_state_events(char *from, xmlnode xmldata) 1682 void handle_state_events(char *from, xmlnode xmldata)
1573 { 1683 {
1574 #if defined JEP0022 || defined JEP0085 1684 #if defined JEP0022 || defined JEP0085
1575 xmlnode state_ns; 1685 xmlnode state_ns = NULL;
1576 const char *body; 1686 const char *body;
1577 char *rname, *jid; 1687 char *rname, *jid;
1578 GSList *sl_buddy; 1688 GSList *sl_buddy;
1579 guint events; 1689 guint events;
1580 guint which_jep = 0; /* 0: none, 1: 85, 2: 22 */ 1690 guint which_jep = 0; /* 0: none, 1: 85, 2: 22 */
1581 struct jep0022 *jep22; 1691 struct jep0022 *jep22 = NULL;
1582 struct jep0085 *jep85; 1692 struct jep0085 *jep85 = NULL;
1583 1693
1584 rname = strchr(from, JID_RESOURCE_SEPARATOR); 1694 rname = strchr(from, JID_RESOURCE_SEPARATOR);
1585 jid = jidtodisp(from); 1695 jid = jidtodisp(from);
1586 sl_buddy = roster_find(jid, jidsearch, ROSTER_TYPE_USER); 1696 sl_buddy = roster_find(jid, jidsearch, ROSTER_TYPE_USER);
1587 1697