Mercurial > pidgin
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); |
