Mercurial > pidgin
comparison libpurple/protocols/simple/simple.c @ 21360:e747ac0c42d6
propagate from branch 'im.pidgin.pidgin.next.minor' (head bd8f1d754a1b94e5ade30c3b135178b236f7b49a)
to branch 'im.pidgin.cpw.resiak.disconnectreason' (head 5d84bcfaddc07cab4419ab9f04b31626421b97ff)
author | Will Thompson <will.thompson@collabora.co.uk> |
---|---|
date | Mon, 15 Oct 2007 10:45:46 +0000 |
parents | ba41f2a60253 74ec24deb267 |
children | 38cc722159ff |
comparison
equal
deleted
inserted
replaced
21359:fe57b8062249 | 21360:e747ac0c42d6 |
---|---|
78 } | 78 } |
79 | 79 |
80 static gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc); | 80 static gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc); |
81 static void send_notify(struct simple_account_data *sip, struct simple_watcher *); | 81 static void send_notify(struct simple_account_data *sip, struct simple_watcher *); |
82 | 82 |
83 static void send_publish(struct simple_account_data *sip); | 83 static void send_open_publish(struct simple_account_data *sip); |
84 static void send_closed_publish(struct simple_account_data *sip); | |
84 | 85 |
85 static void do_notifies(struct simple_account_data *sip) { | 86 static void do_notifies(struct simple_account_data *sip) { |
86 GSList *tmp = sip->watcher; | 87 GSList *tmp = sip->watcher; |
87 purple_debug_info("simple", "do_notifies()\n"); | 88 purple_debug_info("simple", "do_notifies()\n"); |
88 if((sip->republish != -1) || sip->republish < time(NULL)) { | 89 if((sip->republish != -1) || sip->republish < time(NULL)) { |
89 if(purple_account_get_bool(sip->account, "dopublish", TRUE)) { | 90 if(purple_account_get_bool(sip->account, "dopublish", TRUE)) { |
90 send_publish(sip); | 91 send_open_publish(sip); |
91 } | 92 } |
92 } | 93 } |
93 | 94 |
94 while(tmp) { | 95 while(tmp) { |
95 purple_debug_info("simple", "notifying %s\n", ((struct simple_watcher*)tmp->data)->name); | 96 purple_debug_info("simple", "notifying %s\n", ((struct simple_watcher*)tmp->data)->name); |
1022 purple_debug(PURPLE_DEBUG_MISC, "simple", "in process register response response: %d\n", msg->response); | 1023 purple_debug(PURPLE_DEBUG_MISC, "simple", "in process register response response: %d\n", msg->response); |
1023 switch (msg->response) { | 1024 switch (msg->response) { |
1024 case 200: | 1025 case 200: |
1025 if(sip->registerstatus < SIMPLE_REGISTER_COMPLETE) { /* registered */ | 1026 if(sip->registerstatus < SIMPLE_REGISTER_COMPLETE) { /* registered */ |
1026 if(purple_account_get_bool(sip->account, "dopublish", TRUE)) { | 1027 if(purple_account_get_bool(sip->account, "dopublish", TRUE)) { |
1027 send_publish(sip); | 1028 send_open_publish(sip); |
1028 } | 1029 } |
1029 } | 1030 } |
1030 sip->registerstatus = SIMPLE_REGISTER_COMPLETE; | 1031 sip->registerstatus = SIMPLE_REGISTER_COMPLETE; |
1031 purple_connection_set_state(sip->gc, PURPLE_CONNECTED); | 1032 purple_connection_set_state(sip->gc, PURPLE_CONNECTED); |
1032 | 1033 |
1075 } | 1076 } |
1076 | 1077 |
1077 static void process_incoming_notify(struct simple_account_data *sip, struct sipmsg *msg) { | 1078 static void process_incoming_notify(struct simple_account_data *sip, struct sipmsg *msg) { |
1078 gchar *from; | 1079 gchar *from; |
1079 gchar *fromhdr; | 1080 gchar *fromhdr; |
1080 gchar *tmp2; | 1081 gchar *basicstatus_data; |
1081 xmlnode *pidf; | 1082 xmlnode *pidf; |
1082 xmlnode *basicstatus = NULL, *tuple, *status; | 1083 xmlnode *basicstatus = NULL, *tuple, *status; |
1083 gboolean isonline = FALSE; | 1084 gboolean isonline = FALSE; |
1084 | 1085 |
1085 fromhdr = sipmsg_find_header(msg, "From"); | 1086 fromhdr = sipmsg_find_header(msg, "From"); |
1088 | 1089 |
1089 pidf = xmlnode_from_str(msg->body, msg->bodylen); | 1090 pidf = xmlnode_from_str(msg->body, msg->bodylen); |
1090 | 1091 |
1091 if(!pidf) { | 1092 if(!pidf) { |
1092 purple_debug_info("simple", "process_incoming_notify: no parseable pidf\n"); | 1093 purple_debug_info("simple", "process_incoming_notify: no parseable pidf\n"); |
1094 purple_prpl_got_user_status(sip->account, from, "offline", NULL); | |
1095 send_sip_response(sip->gc, msg, 200, "OK", NULL); | |
1093 g_free(from); | 1096 g_free(from); |
1094 send_sip_response(sip->gc, msg, 200, "OK", NULL); | |
1095 return; | 1097 return; |
1096 } | 1098 } |
1097 | 1099 |
1098 if ((tuple = xmlnode_get_child(pidf, "tuple"))) | 1100 if ((tuple = xmlnode_get_child(pidf, "tuple"))) |
1099 if ((status = xmlnode_get_child(tuple, "status"))) | 1101 if ((status = xmlnode_get_child(tuple, "status"))) |
1104 xmlnode_free(pidf); | 1106 xmlnode_free(pidf); |
1105 g_free(from); | 1107 g_free(from); |
1106 return; | 1108 return; |
1107 } | 1109 } |
1108 | 1110 |
1109 tmp2 = xmlnode_get_data(basicstatus); | 1111 basicstatus_data = xmlnode_get_data(basicstatus); |
1110 | 1112 |
1111 if(!tmp2) { | 1113 if(!basicstatus_data) { |
1112 purple_debug_info("simple", "process_incoming_notify: no basic data found\n"); | 1114 purple_debug_info("simple", "process_incoming_notify: no basic data found\n"); |
1113 xmlnode_free(pidf); | 1115 xmlnode_free(pidf); |
1114 g_free(from); | 1116 g_free(from); |
1115 return; | 1117 return; |
1116 } | 1118 } |
1117 | 1119 |
1118 if(strstr(tmp2, "open")) { | 1120 if(strstr(basicstatus_data, "open")) |
1119 isonline = TRUE; | 1121 isonline = TRUE; |
1120 } | 1122 |
1121 | 1123 |
1122 g_free(tmp2); | 1124 if(isonline) |
1123 | 1125 purple_prpl_got_user_status(sip->account, from, "available", NULL); |
1124 if(isonline) purple_prpl_got_user_status(sip->account, from, "available", NULL); | 1126 else |
1125 else purple_prpl_got_user_status(sip->account, from, "offline", NULL); | 1127 purple_prpl_got_user_status(sip->account, from, "offline", NULL); |
1126 | 1128 |
1127 xmlnode_free(pidf); | 1129 xmlnode_free(pidf); |
1128 | |
1129 g_free(from); | 1130 g_free(from); |
1131 g_free(basicstatus_data); | |
1132 | |
1130 send_sip_response(sip->gc, msg, 200, "OK", NULL); | 1133 send_sip_response(sip->gc, msg, 200, "OK", NULL); |
1131 } | 1134 } |
1132 | 1135 |
1133 static unsigned int simple_typing(PurpleConnection *gc, const char *name, PurpleTypingState state) { | 1136 static unsigned int simple_typing(PurpleConnection *gc, const char *name, PurpleTypingState state) { |
1134 struct simple_account_data *sip = gc->proto_data; | 1137 struct simple_account_data *sip = gc->proto_data; |
1191 sip->servername, | 1194 sip->servername, |
1192 sip->status); | 1195 sip->status); |
1193 return doc; | 1196 return doc; |
1194 } | 1197 } |
1195 | 1198 |
1196 | 1199 static gchar* gen_pidf(struct simple_account_data *sip, gboolean open) { |
1197 | |
1198 static gchar* gen_pidf(struct simple_account_data *sip) { | |
1199 gchar *doc = g_strdup_printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | 1200 gchar *doc = g_strdup_printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" |
1200 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n" | 1201 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n" |
1201 "xmlns:im=\"urn:ietf:params:xml:ns:pidf:im\"\n" | 1202 "xmlns:im=\"urn:ietf:params:xml:ns:pidf:im\"\n" |
1202 "entity=\"sip:%s@%s\">\n" | 1203 "entity=\"sip:%s@%s\">\n" |
1203 "<tuple id=\"bs35r9f\">\n" | 1204 "<tuple id=\"bs35r9f\">\n" |
1204 "<status>\n" | 1205 "<status>\n" |
1205 "<basic>open</basic>\n" | 1206 "<basic>%s</basic>\n" |
1206 "</status>\n" | 1207 "</status>\n" |
1207 "<note>%s</note>\n" | 1208 "<note>%s</note>\n" |
1208 "</tuple>\n" | 1209 "</tuple>\n" |
1209 "</presence>", | 1210 "</presence>", |
1210 sip->username, | 1211 sip->username, |
1211 sip->servername, | 1212 sip->servername, |
1212 sip->status); | 1213 (open == TRUE) ? "open" : "closed", |
1214 (open == TRUE) ? sip->status : ""); | |
1213 return doc; | 1215 return doc; |
1214 } | 1216 } |
1215 | 1217 |
1216 static void send_notify(struct simple_account_data *sip, struct simple_watcher *watcher) { | 1218 static void send_notify(struct simple_account_data *sip, struct simple_watcher *watcher) { |
1217 gchar *doc = watcher->needsxpidf ? gen_xpidf(sip) : gen_pidf(sip); | 1219 gchar *doc = watcher->needsxpidf ? gen_xpidf(sip) : gen_pidf(sip, TRUE); |
1218 gchar *hdr = watcher->needsxpidf ? "Event: presence\r\nContent-Type: application/xpidf+xml\r\n" : "Event: presence\r\nContent-Type: application/pidf+xml\r\n"; | 1220 gchar *hdr = watcher->needsxpidf ? "Event: presence\r\nContent-Type: application/xpidf+xml\r\n" : "Event: presence\r\nContent-Type: application/pidf+xml\r\n"; |
1219 send_sip_request(sip->gc, "NOTIFY", watcher->name, watcher->name, hdr, doc, &watcher->dialog, NULL); | 1221 send_sip_request(sip->gc, "NOTIFY", watcher->name, watcher->name, hdr, doc, &watcher->dialog, NULL); |
1220 g_free(doc); | 1222 g_free(doc); |
1221 } | 1223 } |
1222 | 1224 |
1226 sip->republish = -1; | 1228 sip->republish = -1; |
1227 } | 1229 } |
1228 return TRUE; | 1230 return TRUE; |
1229 } | 1231 } |
1230 | 1232 |
1231 static void send_publish(struct simple_account_data *sip) { | 1233 static void send_open_publish(struct simple_account_data *sip) { |
1232 gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); | 1234 gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); |
1233 gchar *doc = gen_pidf(sip); | 1235 gchar *doc = gen_pidf(sip, TRUE); |
1234 send_sip_request(sip->gc, "PUBLISH", uri, uri, | 1236 send_sip_request(sip->gc, "PUBLISH", uri, uri, |
1235 "Expires: 600\r\nEvent: presence\r\n" | 1237 "Expires: 600\r\nEvent: presence\r\n" |
1236 "Content-Type: application/pidf+xml\r\n", | 1238 "Content-Type: application/pidf+xml\r\n", |
1237 doc, NULL, process_publish_response); | 1239 doc, NULL, process_publish_response); |
1238 sip->republish = time(NULL) + 500; | 1240 sip->republish = time(NULL) + 500; |
1241 g_free(uri); | |
1242 g_free(doc); | |
1243 } | |
1244 | |
1245 static void send_closed_publish(struct simple_account_data *sip) { | |
1246 gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); | |
1247 gchar *doc = gen_pidf(sip, FALSE); | |
1248 send_sip_request(sip->gc, "PUBLISH", uri, uri, | |
1249 "Expires: 600\r\nEvent: presence\r\n" | |
1250 "Content-Type: application/pidf+xml\r\n", | |
1251 doc, NULL, process_publish_response); | |
1252 /*sip->republish = time(NULL) + 500;*/ | |
1239 g_free(uri); | 1253 g_free(uri); |
1240 g_free(doc); | 1254 g_free(doc); |
1241 } | 1255 } |
1242 | 1256 |
1243 static void process_incoming_subscribe(struct simple_account_data *sip, struct sipmsg *msg) { | 1257 static void process_incoming_subscribe(struct simple_account_data *sip, struct sipmsg *msg) { |
1758 struct simple_account_data *sip = gc->proto_data; | 1772 struct simple_account_data *sip = gc->proto_data; |
1759 | 1773 |
1760 if(sip) { | 1774 if(sip) { |
1761 /* unregister */ | 1775 /* unregister */ |
1762 if (sip->registerstatus == SIMPLE_REGISTER_COMPLETE) | 1776 if (sip->registerstatus == SIMPLE_REGISTER_COMPLETE) |
1777 { | |
1778 if(purple_account_get_bool(sip->account, | |
1779 "dopublish", | |
1780 TRUE)) | |
1781 send_closed_publish(sip); | |
1782 | |
1763 do_register_exp(sip, 0); | 1783 do_register_exp(sip, 0); |
1784 } | |
1764 connection_free_all(sip); | 1785 connection_free_all(sip); |
1765 | 1786 |
1766 if (sip->query_data != NULL) | 1787 if (sip->query_data != NULL) |
1767 purple_dnsquery_destroy(sip->query_data); | 1788 purple_dnsquery_destroy(sip->query_data); |
1768 | 1789 |