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