Mercurial > ~mikael > mcabber > hg
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 |