comparison libpurple/protocols/bonjour/mdns_common.c @ 18859:c1546f6c0432

Yay for code reuse.
author Daniel Atallah <daniel.atallah@gmail.com>
date Fri, 10 Aug 2007 01:29:48 +0000
parents 1787e601aafc
children 2d6d936867bc
comparison
equal deleted inserted replaced
18858:f773aa054dca 18859:c1546f6c0432
27 27
28 28
29 /** 29 /**
30 * Allocate space for the dns-sd data. 30 * Allocate space for the dns-sd data.
31 */ 31 */
32 BonjourDnsSd * 32 BonjourDnsSd * bonjour_dns_sd_new() {
33 bonjour_dns_sd_new()
34 {
35 BonjourDnsSd *data = g_new0(BonjourDnsSd, 1); 33 BonjourDnsSd *data = g_new0(BonjourDnsSd, 1);
36
37 return data; 34 return data;
38 } 35 }
39 36
40 /** 37 /**
41 * Deallocate the space of the dns-sd data. 38 * Deallocate the space of the dns-sd data.
42 */ 39 */
43 void 40 void bonjour_dns_sd_free(BonjourDnsSd *data) {
44 bonjour_dns_sd_free(BonjourDnsSd *data)
45 {
46 g_free(data->first); 41 g_free(data->first);
47 g_free(data->last); 42 g_free(data->last);
48 g_free(data->phsh); 43 g_free(data->phsh);
49 g_free(data->status); 44 g_free(data->status);
50 g_free(data->vc); 45 g_free(data->vc);
51 g_free(data->msg); 46 g_free(data->msg);
52 g_free(data); 47 g_free(data);
53 } 48 }
54 49
50 static GSList *generate_presence_txt_records(BonjourDnsSd *data) {
51 GSList *ret = NULL;
52 PurpleKeyValuePair *kvp;
53 char portstring[6];
54 const char *jid, *aim, *email;
55
56 /* Convert the port to a string */
57 snprintf(portstring, sizeof(portstring), "%d", data->port_p2pj);
58
59 jid = purple_account_get_string(data->account, "jid", NULL);
60 aim = purple_account_get_string(data->account, "AIM", NULL);
61 email = purple_account_get_string(data->account, "email", NULL);
62
63 #define _M_ADD_R(k, v) \
64 kvp = g_new0(PurpleKeyValuePair, 1); \
65 kvp->key = g_strdup(k); \
66 kvp->value = g_strdup(v); \
67 ret = g_slist_prepend(ret, kvp); \
68
69 /* We should try to follow XEP-0174, but some clients have "issues", so we humor them.
70 * See http://telepathy.freedesktop.org/wiki/SalutInteroperability
71 */
72
73 /* Needed by iChat */
74 _M_ADD_R("txtvers", "1")
75 /* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
76 _M_ADD_R("1st", data->first)
77 /* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
78 _M_ADD_R("last", data->last)
79 /* Needed by Adium */
80 _M_ADD_R("port.p2pj", portstring)
81 /* Needed by iChat, Gaim/Pidgin <= 2.0.1 */
82 _M_ADD_R("status", data->status)
83 _M_ADD_R("node", "libpurple")
84 _M_ADD_R("ver", VERSION)
85 /* Currently always set to "!" since we don't support AV and wont ever be in a conference */
86 _M_ADD_R("vc", data->vc)
87 if (email != NULL && *email != '\0') {
88 _M_ADD_R("email", email)
89 }
90 if (jid != NULL && *jid != '\0') {
91 _M_ADD_R("jid", jid)
92 }
93 /* Nonstandard, but used by iChat */
94 if (aim != NULL && *aim != '\0') {
95 _M_ADD_R("AIM", aim)
96 }
97 if (data->msg != NULL && *data->msg != '\0') {
98 _M_ADD_R("msg", data->msg)
99 }
100 if (data->phsh != NULL && *data->phsh != '\0') {
101 _M_ADD_R("phsh", data->phsh)
102 }
103
104 /* TODO: ext, nick */
105 return ret;
106 }
107
108 static void free_presence_txt_records(GSList *lst) {
109 PurpleKeyValuePair *kvp;
110 while(lst) {
111 kvp = lst->data;
112 g_free(kvp->key);
113 g_free(kvp->value);
114 g_free(kvp);
115 lst = g_slist_remove(lst, lst->data);
116 }
117 }
118
119 static gboolean publish_presence(BonjourDnsSd *data, PublishType type) {
120 GSList *txt_records;
121 gboolean ret;
122
123 txt_records = generate_presence_txt_records(data);
124 ret = _mdns_publish(data, type, txt_records);
125 free_presence_txt_records(txt_records);
126
127 return ret;
128 }
129
55 /** 130 /**
56 * Send a new dns-sd packet updating our status. 131 * Send a new dns-sd packet updating our status.
57 */ 132 */
58 void 133 void bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message) {
59 bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message) {
60 g_free(data->status); 134 g_free(data->status);
61 g_free(data->msg); 135 g_free(data->msg);
62 136
63 data->status = g_strdup(status); 137 data->status = g_strdup(status);
64 data->msg = g_strdup(status_message); 138 data->msg = g_strdup(status_message);
65 139
66 /* Update our text record with the new status */ 140 /* Update our text record with the new status */
67 _mdns_publish(data, PUBLISH_UPDATE); /* <--We must control the errors */ 141 publish_presence(data, PUBLISH_UPDATE);
68 } 142 }
69 143
70 /** 144 /**
71 * Retrieve the buddy icon blob 145 * Retrieve the buddy icon blob
72 */ 146 */
73 void bonjour_dns_sd_retrieve_buddy_icon(BonjourBuddy* buddy) { 147 void bonjour_dns_sd_retrieve_buddy_icon(BonjourBuddy* buddy) {
74 _mdns_retrieve_buddy_icon(buddy); 148 _mdns_retrieve_buddy_icon(buddy);
75 } 149 }
76 150
77 void 151 void bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data) {
78 bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data) {
79 PurpleStoredImage *img; 152 PurpleStoredImage *img;
80 153
81 if ((img = purple_buddy_icons_find_account_icon(data->account))) { 154 if ((img = purple_buddy_icons_find_account_icon(data->account))) {
82 gconstpointer avatar_data; 155 gconstpointer avatar_data;
83 gsize avatar_len; 156 gsize avatar_len;
105 data->phsh = g_strdup(hash); 178 data->phsh = g_strdup(hash);
106 179
107 g_free(enc); 180 g_free(enc);
108 181
109 /* Update our TXT record */ 182 /* Update our TXT record */
110 _mdns_publish(data, PUBLISH_UPDATE); 183 publish_presence(data, PUBLISH_UPDATE);
111 } 184 }
112 185
113 purple_imgstore_unref(img); 186 purple_imgstore_unref(img);
114 } else { 187 } else {
115 /* We need to do this regardless of whether data->phsh is set so that we 188 /* We need to do this regardless of whether data->phsh is set so that we
118 if (data->phsh != NULL) { 191 if (data->phsh != NULL) {
119 /* Clear the buddy icon */ 192 /* Clear the buddy icon */
120 g_free(data->phsh); 193 g_free(data->phsh);
121 data->phsh = NULL; 194 data->phsh = NULL;
122 /* Update our TXT record */ 195 /* Update our TXT record */
123 _mdns_publish(data, PUBLISH_UPDATE); 196 publish_presence(data, PUBLISH_UPDATE);
124 } 197 }
125 } 198 }
126 } 199 }
127 200
128 /** 201 /**
129 * Advertise our presence within the dns-sd daemon and start browsing 202 * Advertise our presence within the dns-sd daemon and start browsing
130 * for other bonjour peers. 203 * for other bonjour peers.
131 */ 204 */
132 gboolean 205 gboolean bonjour_dns_sd_start(BonjourDnsSd *data) {
133 bonjour_dns_sd_start(BonjourDnsSd *data)
134 {
135 PurpleConnection *gc;
136
137 gc = purple_account_get_connection(data->account);
138 206
139 /* Initialize the dns-sd data and session */ 207 /* Initialize the dns-sd data and session */
140 if (!_mdns_init_session(data)) 208 if (!_mdns_init_session(data))
141 return FALSE; 209 return FALSE;
142 210
143 /* Publish our bonjour IM client at the mDNS daemon */ 211 /* Publish our bonjour IM client at the mDNS daemon */
144 if (!_mdns_publish(data, PUBLISH_START)) 212 if (!publish_presence(data, PUBLISH_START))
145 return FALSE; 213 return FALSE;
146 214
147 /* Advise the daemon that we are waiting for connections */ 215 /* Advise the daemon that we are waiting for connections */
148 if (!_mdns_browse(data)) { 216 if (!_mdns_browse(data)) {
149 purple_debug_error("bonjour", "Unable to get service."); 217 purple_debug_error("bonjour", "Unable to get service.");
155 223
156 /** 224 /**
157 * Unregister the "_presence._tcp" service at the mDNS daemon. 225 * Unregister the "_presence._tcp" service at the mDNS daemon.
158 */ 226 */
159 227
160 void 228 void bonjour_dns_sd_stop(BonjourDnsSd *data) {
161 bonjour_dns_sd_stop(BonjourDnsSd *data) {
162 _mdns_stop(data); 229 _mdns_stop(data);
163 } 230 }