comparison src/protocols/simple/simple.c @ 13177:891be2f09b5c

[gaim-migrate @ 15540] adding support for xpidf used by windows messenger and changing Contact headers to be accepted by LCS committer: Tailor Script <tailor@pidgin.im>
author Thomas Butter <tbutter>
date Wed, 08 Feb 2006 05:53:52 +0000
parents d0ae6489a0fb
children 2d68ea9616b3
comparison
equal deleted inserted replaced
13176:dbe0198ced4b 13177:891be2f09b5c
139 entry = entry->next; 139 entry = entry->next;
140 } 140 }
141 return NULL; 141 return NULL;
142 } 142 }
143 143
144 static struct simple_watcher *watcher_create(struct simple_account_data *sip, gchar *name, gchar *callid, gchar *ourtag, gchar *theirtag) { 144 static struct simple_watcher *watcher_create(struct simple_account_data *sip, gchar *name, gchar *callid, gchar *ourtag, gchar *theirtag, int needsxpidf) {
145 struct simple_watcher *watcher = g_new0(struct simple_watcher, 1); 145 struct simple_watcher *watcher = g_new0(struct simple_watcher, 1);
146 watcher->name = g_strdup(name); 146 watcher->name = g_strdup(name);
147 watcher->dialog.callid = g_strdup(callid); 147 watcher->dialog.callid = g_strdup(callid);
148 watcher->dialog.ourtag = g_strdup(ourtag); 148 watcher->dialog.ourtag = g_strdup(ourtag);
149 watcher->dialog.theirtag = g_strdup(theirtag); 149 watcher->dialog.theirtag = g_strdup(theirtag);
150 watcher->needsxpidf = needsxpidf;
150 sip->watcher = g_slist_append(sip->watcher, watcher); 151 sip->watcher = g_slist_append(sip->watcher, watcher);
151 return watcher; 152 return watcher;
152 } 153 }
153 154
154 static void watcher_remove(struct simple_account_data *sip, gchar *name) { 155 static void watcher_remove(struct simple_account_data *sip, gchar *name) {
605 sendout_pkt(gc,buf); 606 sendout_pkt(gc,buf);
606 607
607 g_free(buf); 608 g_free(buf);
608 } 609 }
609 610
611 static char *get_contact(struct simple_account_data *sip) {
612 return g_strdup_printf("<sip:%s@%s:%d;transport=%s>;methods=\"MESSAGE, SUBSCRIBE, NOTIFY\"", sip->username, gaim_network_get_my_ip(-1), sip->listenport, sip->udp ? "udp" : "tcp");
613 }
614
610 static void do_register_exp(struct simple_account_data *sip, int expire) { 615 static void do_register_exp(struct simple_account_data *sip, int expire) {
611 char *uri = g_strdup_printf("sip:%s",sip->servername); 616 char *uri = g_strdup_printf("sip:%s",sip->servername);
612 char *to = g_strdup_printf("sip:%s@%s",sip->username,sip->servername); 617 char *to = g_strdup_printf("sip:%s@%s",sip->username,sip->servername);
613 char *contact = g_strdup_printf("Contact: <sip:%s@%s:%d;transport=%s>;methods=\"MESSAGE, SUBSCRIBE, NOTIFY\"\r\nExpires: %d\r\n", sip->username, gaim_network_get_my_ip(-1), sip->listenport, sip->udp ? "udp" : "tcp", expire); 618 char *contact = get_contact(sip);
619 char *hdr = g_strdup_printf("Contact: %s\r\nExpires: %d\r\n", contact, expire);
620 g_free(contact);
614 621
615 sip->registerstatus = 1; 622 sip->registerstatus = 1;
616 623
617 if(expire) { 624 if(expire) {
618 sip->reregister = time(NULL) + expire - 50; 625 sip->reregister = time(NULL) + expire - 50;
619 } else { 626 } else {
620 sip->reregister = time(NULL) + 600; 627 sip->reregister = time(NULL) + 600;
621 } 628 }
622 send_sip_request(sip->gc,"REGISTER",uri,to, contact, "", NULL, process_register_response); 629 send_sip_request(sip->gc,"REGISTER",uri,to, hdr, "", NULL, process_register_response);
623 g_free(contact); 630 g_free(hdr);
624 g_free(uri); 631 g_free(uri);
625 g_free(to); 632 g_free(to);
626 } 633 }
627 634
628 static void do_register(struct simple_account_data *sip) { 635 static void do_register(struct simple_account_data *sip) {
672 g_free(to); 679 g_free(to);
673 return TRUE; 680 return TRUE;
674 } 681 }
675 682
676 static void simple_subscribe(struct simple_account_data *sip, struct simple_buddy *buddy) { 683 static void simple_subscribe(struct simple_account_data *sip, struct simple_buddy *buddy) {
677 gchar *contact = "Expires: 300\r\nAccept: application/pidf+xml\r\nEvent: presence\r\n"; 684 gchar *contact = "Expires: 300\r\nAccept: application/pidf+xml, application/xpidf+xml\r\nEvent: presence\r\n";
678 gchar *to; 685 gchar *to;
686 gchar *tmp;
679 if(strstr(buddy->name,"sip:")) to = g_strdup(buddy->name); 687 if(strstr(buddy->name,"sip:")) to = g_strdup(buddy->name);
680 else to = g_strdup_printf("sip:%s",buddy->name); 688 else to = g_strdup_printf("sip:%s",buddy->name);
681 contact = g_strdup_printf("%sContact: <sip:%s@%s>\r\n", contact, sip->username, sip->servername); 689 tmp = get_contact(sip);
690 contact = g_strdup_printf("%sContact: %s\r\n", contact, tmp);
691 g_free(tmp);
682 /* subscribe to buddy presence 692 /* subscribe to buddy presence
683 * we dont need to know the status so we do not need a callback */ 693 * we dont need to know the status so we do not need a callback */
684 694
685 send_sip_request(sip->gc, "SUBSCRIBE",to, to, contact, "", NULL, process_subscribe_response); 695 send_sip_request(sip->gc, "SUBSCRIBE",to, to, contact, "", NULL, process_subscribe_response);
686 696
935 return tmp; 945 return tmp;
936 } 946 }
937 return g_strdup(tmp); 947 return g_strdup(tmp);
938 } 948 }
939 949
950 static gchar* gen_xpidf(struct simple_account_data *sip) {
951 gchar *doc = g_strdup_printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
952 "<presence>\n"
953 "<presentity uri=\"sip:%s@%s;method=SUBSCRIBE\"/>\n"
954 "<display name=\"sip:%s@%s\"/>\n"
955 "<atom id=\"1234\">\n"
956 "<address uri=\"sip:%s@%s\">\n"
957 "<status status=\"%s\"/>\n"
958 "</address>\n"
959 "</atom>\n"
960 "</presence>\n",
961 sip->username,
962 sip->servername,
963 sip->username,
964 sip->servername,
965 sip->username,
966 sip->servername,
967 sip->status);
968 return doc;
969 }
970
971
972
940 static gchar* gen_pidf(struct simple_account_data *sip) { 973 static gchar* gen_pidf(struct simple_account_data *sip) {
941 gchar *doc = g_strdup_printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 974 gchar *doc = g_strdup_printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
942 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n" 975 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n"
943 "xmlns:im=\"urn:ietf:params:xml:ns:pidf:im\"\n" 976 "xmlns:im=\"urn:ietf:params:xml:ns:pidf:im\"\n"
944 "entity=\"sip:%s@%s\">\n" 977 "entity=\"sip:%s@%s\">\n"
954 sip->status); 987 sip->status);
955 return doc; 988 return doc;
956 } 989 }
957 990
958 static void send_notify(struct simple_account_data *sip, struct simple_watcher *watcher) { 991 static void send_notify(struct simple_account_data *sip, struct simple_watcher *watcher) {
959 gchar *doc = gen_pidf(sip); 992 gchar *doc = watcher->needsxpidf ? gen_xpidf(sip) : gen_pidf(sip);
960 send_sip_request(sip->gc, "NOTIFY", watcher->name, watcher->name, "Event: presence\r\nContent-Type: application/pidf+xml\r\n", doc, &watcher->dialog, NULL); 993 gchar *hdr = watcher->needsxpidf ? "Event: presence\r\nContent-Type: application/xpidf+xml\r\n" : "Event: presence\r\nContent-Type: application/pidf+xml\r\n";
994 send_sip_request(sip->gc, "NOTIFY", watcher->name, watcher->name, hdr, doc, &watcher->dialog, NULL);
961 g_free(doc); 995 g_free(doc);
962 } 996 }
963 997
964 static gboolean process_publish_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { 998 static gboolean process_publish_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) {
965 if(msg->response != 200 && msg->response != 408) { 999 if(msg->response != 200 && msg->response != 408) {
989 if(!ourtag) { 1023 if(!ourtag) {
990 tagadded = TRUE; 1024 tagadded = TRUE;
991 ourtag = gentag(); 1025 ourtag = gentag();
992 } 1026 }
993 if(!watcher) { /* new subscription */ 1027 if(!watcher) { /* new subscription */
1028 gchar *acceptheader = sipmsg_find_header(msg, "Accept");
1029 int needsxpidf = 0;
994 if(!gaim_privacy_check(sip->account, from)) { 1030 if(!gaim_privacy_check(sip->account, from)) {
995 send_sip_response(sip->gc, msg, 202, "Ok", NULL); 1031 send_sip_response(sip->gc, msg, 202, "Ok", NULL);
996 goto privend; 1032 goto privend;
997 } 1033 }
998 watcher = watcher_create(sip, from, callid, ourtag, theirtag); 1034 if(acceptheader) {
1035 gchar *tmp = acceptheader;
1036 int foundpidf = 0;
1037 int foundxpidf = 0;
1038 while(tmp && tmp < acceptheader + strlen(acceptheader)) {
1039 gchar *tmp2 = strchr(tmp, ',');
1040 if(tmp2) *tmp2 = '\0';
1041 if(!strcmp("application/pidf+xml",tmp))
1042 foundpidf = 1;
1043 if(!strcmp("application/xpidf+xml",tmp))
1044 foundxpidf = 1;
1045 if(tmp2) {
1046 *tmp2 = ',';
1047 tmp = tmp2;
1048 while(*tmp == ' ') tmp++;
1049 } else
1050 tmp = 0;
1051 }
1052 if(!foundpidf && foundxpidf) needsxpidf = 1;
1053 g_free(acceptheader);
1054 }
1055 watcher = watcher_create(sip, from, callid, ourtag, theirtag, needsxpidf);
999 } 1056 }
1000 if(tagadded) { 1057 if(tagadded) {
1001 gchar *to = g_strdup_printf("%s;tag=%s", sipmsg_find_header(msg, "To"), ourtag); 1058 gchar *to = g_strdup_printf("%s;tag=%s", sipmsg_find_header(msg, "To"), ourtag);
1002 sipmsg_remove_header(msg, "To"); 1059 sipmsg_remove_header(msg, "To");
1003 sipmsg_add_header(msg, "To", to); 1060 sipmsg_add_header(msg, "To", to);
1005 if(expire) 1062 if(expire)
1006 watcher->expire = time(NULL) + strtol(expire, NULL, 10); 1063 watcher->expire = time(NULL) + strtol(expire, NULL, 10);
1007 else 1064 else
1008 watcher->expire = time(NULL) + 600; 1065 watcher->expire = time(NULL) + 600;
1009 sipmsg_remove_header(msg, "Contact"); 1066 sipmsg_remove_header(msg, "Contact");
1010 tmp = g_strdup_printf("<sip:%s@%s>",sip->username, sip->servername); 1067 tmp = get_contact(sip);
1011 sipmsg_add_header(msg, "Contact", tmp); 1068 sipmsg_add_header(msg, "Contact", tmp);
1069 g_free(tmp);
1012 gaim_debug_info("simple","got subscribe: name %s ourtag %s theirtag %s callid %s\n", watcher->name, watcher->dialog.ourtag, watcher->dialog.theirtag, watcher->dialog.callid); 1070 gaim_debug_info("simple","got subscribe: name %s ourtag %s theirtag %s callid %s\n", watcher->name, watcher->dialog.ourtag, watcher->dialog.theirtag, watcher->dialog.callid);
1013 send_sip_response(sip->gc, msg, 200, "Ok", NULL); 1071 send_sip_response(sip->gc, msg, 200, "Ok", NULL);
1014 g_free(tmp);
1015 send_notify(sip, watcher); 1072 send_notify(sip, watcher);
1016 privend: 1073 privend:
1017 g_free(from); 1074 g_free(from);
1018 g_free(theirtag); 1075 g_free(theirtag);
1019 g_free(ourtag); 1076 g_free(ourtag);