00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <libxml/parser.h>
00023
00024 #include "../../dprint.h"
00025 #include "../../str.h"
00026 #include "../tm/tm_load.h"
00027 #include "../pua/pua_bind.h"
00028 #include "../pua/pidf.h"
00029
00030 #include "purple.h"
00031 #include "purple_sip.h"
00032
00033 extern struct tm_binds tmb;
00034 extern send_publish_t pua_send_publish;
00035
00036
00037 int purple_send_sip_msg(char *to, char *from, char *msg) {
00038 LM_DBG("sending message from %s to %s\n", from, to);
00039 str msg_type = { "MESSAGE", 7 };
00040 str ruri, hdr, fromstr, tostr, msgstr;
00041 char hdr_buf[512], ruri_buf[512];
00042
00043 ruri.s = ruri_buf;
00044 ruri.len = snprintf(ruri_buf, sizeof(ruri_buf), "%s;proto=purple", to);
00045
00046 hdr.s = hdr_buf;
00047 hdr.len = snprintf(hdr_buf, sizeof(hdr_buf), "Content-type: text/plain" CRLF "Contact: %s" CRLF, from);
00048
00049 fromstr.s = from;
00050 fromstr.len = strlen(from);
00051 tostr.s = to;
00052 tostr.len = strlen(to);
00053 msgstr.s = msg;
00054 msgstr.len = strlen(msg);
00055
00056 if (tmb.t_request(&msg_type, &ruri, &tostr, &fromstr, &hdr, &msgstr, 0, 0, 0) < 0) {
00057 LM_ERR("error sending request\n");
00058 return -1;
00059 }
00060 LM_DBG("message sent successfully\n");
00061 return 0;
00062 }
00063
00064 static str* build_pidf(char *uri, char *id, enum purple_publish_basic basic, enum purple_publish_activity activity, const char *note) {
00065 LM_DBG("build pidf : %s, %d, %d, %s\n", uri, basic, activity, note);
00066 str* body = NULL;
00067 xmlDocPtr doc = NULL;
00068 xmlNodePtr root_node = NULL, status_node = NULL;
00069 xmlNodePtr tuple_node = NULL, basic_node = NULL;
00070 xmlNodePtr person_node = NULL, activities_node = NULL;
00071 xmlNsPtr pidf_ns, dm_ns, rpid_ns, cipid_ns;
00072 char* entity = NULL;
00073
00074 entity = (char*)pkg_malloc(7+ strlen(uri)*sizeof(char));
00075 if(entity == NULL) {
00076 LM_ERR("no more memory\n");
00077 goto error;
00078 }
00079 strcpy(entity, "pres:");
00080 memcpy(entity+5, uri+4, strlen(uri)-4);
00081 entity[1+ strlen(uri)] = '\0';
00082 LM_DBG("building pidf for entity: %s\n", entity);
00083
00084 doc = xmlNewDoc(BAD_CAST "1.0");
00085 if(doc == NULL) {
00086 LM_ERR("allocating new xml doc\n");
00087 goto error;
00088 }
00089
00090 root_node = xmlNewNode(NULL, BAD_CAST "presence");
00091 if(root_node == 0) {
00092 LM_ERR("extracting presence node\n");
00093 goto error;
00094 }
00095 xmlDocSetRootElement(doc, root_node);
00096 xmlNewProp(root_node, BAD_CAST "entity", BAD_CAST entity);
00097
00098 pidf_ns = xmlNewNs(root_node, BAD_CAST "urn:ietf:params:xml:ns:pidf", NULL);
00099 dm_ns = xmlNewNs(root_node, BAD_CAST "urn:ietf:params:xml:ns:pidf:data-model", BAD_CAST "dm");
00100 rpid_ns = xmlNewNs(root_node, BAD_CAST "urn:ietf:params:xml:ns:pidf:rpid", BAD_CAST "rpid");
00101 cipid_ns = xmlNewNs(root_node, BAD_CAST "urn:ietf:params:xml:ns:pidf:cipid", BAD_CAST "c");
00102
00103 tuple_node = xmlNewChild(root_node, NULL, BAD_CAST "tuple", NULL);
00104 if( tuple_node == NULL) {
00105 LM_ERR("while adding child\n");
00106 goto error;
00107 }
00108 xmlNewProp(tuple_node, BAD_CAST "id", BAD_CAST id);
00109
00110 status_node = xmlNewChild(tuple_node, pidf_ns, BAD_CAST "status", NULL);
00111 if( status_node ==NULL) {
00112 LM_ERR("while adding child\n");
00113 goto error;
00114 }
00115
00116 switch (basic) {
00117 case PURPLE_BASIC_OPEN:
00118 basic_node = xmlNewChild(status_node, pidf_ns, BAD_CAST "basic", BAD_CAST "open");
00119 if(basic_node == NULL) {
00120 LM_ERR("while adding child\n");
00121 goto error;
00122 }
00123 break;
00124
00125 case PURPLE_BASIC_CLOSED:
00126 basic_node = xmlNewChild(status_node, pidf_ns, BAD_CAST "basic", BAD_CAST "closed") ;
00127 if(basic_node == NULL) {
00128 LM_ERR("while adding child\n");
00129 goto error;
00130 }
00131 break;
00132 default:
00133 break;
00134 }
00135
00136 person_node = xmlNewChild(root_node, dm_ns, BAD_CAST "person", NULL);
00137 if (person_node == NULL) {
00138 LM_ERR("while adding child\n");
00139 goto error;
00140 }
00141 xmlNewProp(person_node, BAD_CAST "id", BAD_CAST id);
00142
00143 activities_node = xmlNewChild(person_node, rpid_ns, BAD_CAST "activities", NULL);
00144 if (activities_node == NULL) {
00145 LM_ERR("while adding child\n");
00146 goto error;
00147 }
00148
00149 switch (activity) {
00150 case PURPLE_ACTIVITY_AVAILABLE:
00151 xmlNewChild(activities_node, rpid_ns, BAD_CAST "unknown", NULL);
00152 xmlNewChild(person_node, dm_ns, BAD_CAST "note", (note != NULL) ? BAD_CAST note : NULL);
00153 break;
00154 case PURPLE_ACTIVITY_BUSY:
00155 xmlNewChild(activities_node, rpid_ns, BAD_CAST "busy", NULL);
00156 xmlNewChild(activities_node, rpid_ns, BAD_CAST "unknown", NULL);
00157 if (note == NULL)
00158 xmlNewChild(person_node, dm_ns, BAD_CAST "note", BAD_CAST "Busy");
00159 break;
00160 case PURPLE_ACTIVITY_AWAY:
00161 xmlNewChild(activities_node, rpid_ns, BAD_CAST "away", NULL);
00162 xmlNewChild(activities_node, rpid_ns, BAD_CAST "unknown", NULL);
00163 if (note == NULL)
00164 xmlNewChild(person_node, dm_ns, BAD_CAST "note", BAD_CAST "Away");
00165 break;
00166 default:
00167 break;
00168 }
00169
00170 if (note != NULL)
00171 xmlNewChild(person_node, dm_ns, BAD_CAST "note", BAD_CAST note);
00172
00173
00174 body = (str*)pkg_malloc(sizeof(str));
00175 if(body == NULL) {
00176 LM_ERR("no more memory\n");
00177 goto error;
00178 }
00179 xmlDocDumpFormatMemory(doc, (xmlChar**)(void*)&body->s, &body->len, 1);
00180
00181 if(entity)
00182 pkg_free(entity);
00183 xmlFreeDoc(doc);
00184
00185 return body;
00186
00187 error:
00188 if(entity)
00189 pkg_free(entity);
00190 if(body) {
00191 if(body->s) {
00192 xmlFree(body->s);
00193 }
00194 pkg_free(body);
00195 }
00196 if(doc) {
00197 xmlFreeDoc(doc);
00198 }
00199
00200 return NULL;
00201 }
00202
00203
00204
00205 int purple_send_sip_publish(char *from, char *tupleid, enum purple_publish_basic basic, enum purple_publish_activity primitive, const char *note) {
00206
00207 LM_DBG("publishing presence for <%s> with tuple [%s]\n", from, tupleid);
00208
00209 char pres_buff[512];
00210 publ_info_t publ;
00211
00212 memset(&publ, 0, sizeof(publ_info_t));
00213
00214 str pres_uri;
00215 pres_uri.s = pres_buff;
00216 pres_uri.len = sprintf(pres_buff, "%s;proto=purple", from);
00217
00218 publ.pres_uri = &pres_uri;
00219 publ.source_flag = PURPLE_PUBLISH;
00220 publ.event = PRESENCE_EVENT;
00221
00222 str *body = NULL;
00223 if (basic == PURPLE_BASIC_OPEN) {
00224 body = build_pidf(from, tupleid, basic, primitive, note);
00225 publ.expires = 3600;
00226 }
00227 else {
00228 publ.body = NULL;
00229 publ.expires = 0;
00230 }
00231
00232 publ.body = body;
00233
00234 if(pua_send_publish(&publ) < 0) {
00235 LM_ERR("error while sending publish\n");
00236 return -1;
00237 }
00238 LM_DBG("publish sent successfully for <%s>\n", from);
00239 return 0;
00240 }
00241
00242