all: updated FSF address in GPL text
[sip-router] / modules / pua_xmpp / simple2xmpp.c
1 /*
2  * $Id: simple2xmpp.c 1666 2007-03-02 13:40:09Z anca_vamanu $
3  *
4  * pua_xmpp module - presence SIP - XMPP Gateway
5  *
6  * Copyright (C) 2007 Voice Sistem S.R.L.
7  *
8  * This file is part of Kamailio, a free SIP server.
9  *
10  * Kamailio is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * Kamailio is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License 
21  * along with this program; if not, write to the Free Software 
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  * History:
25  * --------
26  *  2007-03-29  initial version (anca)
27  */
28
29 /*! \file
30  * \brief Kamailio presence gateway: SIP/SIMPLE -- XMPP (pua_xmpp)
31  */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <libxml/parser.h>
36
37 #include "../../ut.h"
38 #include "../../lib/kcore/cmpapi.h"
39 #include "../../dprint.h"
40 #include "../../parser/msg_parser.h"
41 #include "../../parser/parse_from.h"
42 #include "../../parser/parse_expires.h"
43 #include "../../parser/parse_content.h"
44 #include "../../parser/parse_fline.h"
45 #include "../../mem/mem.h"
46 #include "pua_xmpp.h"
47 #include "simple2xmpp.h"
48
49 int winfo2xmpp(str* to_uri, str* body, str* id);
50 int build_xmpp_content(str* to_uri, str* from_uri, str* body, str* id, int is_terminated);
51
52 int Notify2Xmpp(struct sip_msg* msg, char* s1, char* s2)
53 {
54         struct to_body *pto, TO = {0}, *pfrom = NULL;
55         str to_uri;
56         char* uri= NULL;
57         str from_uri;
58         struct hdr_field* hdr= NULL;
59         str body;
60         int is_terminated= 0;
61         str id;
62         ua_pres_t dialog;
63         int event_flag= 0;
64
65         memset(&dialog, 0, sizeof(ua_pres_t));
66         
67         LM_DBG("start...\n\n");
68
69         if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
70         {
71                 LM_ERR("parsing headers\n");
72                 return -1;
73         }
74         if((!msg->event ) ||(msg->event->body.len<=0))
75         {
76                 LM_ERR("Missing event header field value\n");
77                 return -1;
78         }
79
80         if( msg->to==NULL || msg->to->body.s==NULL)
81         {
82                 LM_ERR("cannot parse TO header\n");
83                 return -1;
84         }
85
86         if(msg->to->parsed != NULL)
87         {
88                 pto = (struct to_body*)msg->to->parsed;
89                 LM_DBG("'To' header ALREADY PARSED:<%.*s>\n",pto->uri.len,pto->uri.s);
90         }
91         else
92         {
93                 parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO);
94                 if(TO.uri.len <= 0) 
95                 {
96                         LM_ERR("'To' header NOT parsed\n");
97                         goto error;
98                 }
99                 pto = &TO;
100         }
101
102         dialog.watcher_uri= &pto->uri;
103         
104         uri=(char*)pkg_malloc(sizeof(char)*( pto->uri.len+1));
105         if(uri== NULL)
106         {
107                 LM_ERR("no more memory\n");
108                 goto error;
109         }
110         memcpy(uri, pto->uri.s, pto->uri.len);
111         uri[pto->uri.len]= '\0';
112         to_uri.s= duri_sip_xmpp(uri);
113         if(to_uri.s== NULL)
114         {
115                 LM_ERR("while decoding sip uri in xmpp\n");
116                 pkg_free(uri);
117                 goto error;
118         }       
119         to_uri.len= strlen(to_uri.s);
120         pkg_free(uri);
121
122         if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
123         {  
124                 LM_ERR("to tag value not parsed\n");
125                 goto error;
126         }
127         id=  pto->tag_value;
128         dialog.from_tag= id;
129
130         if( msg->callid==NULL || msg->callid->body.s==NULL)
131         {
132                 LM_ERR("cannot parse callid header\n");
133                 goto error;
134         }
135         dialog.call_id = msg->callid->body;
136
137         if (!msg->from || !msg->from->body.s)
138         {
139                 LM_ERR("ERROR cannot find 'from' header!\n");
140                 goto error;
141         }
142         if (msg->from->parsed == NULL)
143         {
144                 LM_ERR("'From' header not parsed\n");
145                 /* parsing from header */
146                 if ( parse_from_header( msg )<0 ) 
147                 {
148                         LM_ERR("ERROR cannot parse From header\n");
149                         goto error;
150                 }
151         }
152         pfrom = (struct to_body*)msg->from->parsed;
153         dialog.pres_uri= &pfrom->uri;
154         
155         uri=(char*)pkg_malloc(sizeof(char)*( pfrom->uri.len+1));
156         if(uri== NULL)
157         {
158                 LM_ERR("no more memory\n");
159                 goto error;
160         }
161         memcpy(uri, pfrom->uri.s, pfrom->uri.len);
162         uri[pfrom->uri.len]= '\0';
163         
164         from_uri.s= euri_sip_xmpp(uri);
165         if(from_uri.s== NULL)
166         {
167                 LM_ERR("while encoding sip uri in xmpp\n");
168                 pkg_free(uri);
169                 goto error;
170         }       
171         from_uri.len= strlen(from_uri.s);
172         pkg_free(uri);
173         
174         if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
175         {
176                 LM_ERR("no from tag value present\n");
177                 goto error;
178         }
179
180         dialog.to_tag= pfrom->tag_value;
181         dialog.flag|= XMPP_SUBSCRIBE;
182         if(msg->event->body.len== 8 && 
183                         (strncmp(msg->event->body.s,"presence",8 )==0))
184                 event_flag|= PRESENCE_EVENT;
185         else
186         if(msg->event->body.len== 14 && 
187                         (strncmp(msg->event->body.s,"presence.winfo",14 )==0))
188                 event_flag|= PWINFO_EVENT;
189         else
190         {
191                 LM_ERR("wrong event\n");
192                 goto error;
193         }       
194         dialog.event= event_flag;
195         
196         if(pua_is_dialog(&dialog)< 0) // verify if within a stored dialog
197         {
198                 LM_ERR("Notify in a non existing dialog\n");
199                 goto error;
200         }
201         /*constructing the xml body*/
202         if(get_content_length(msg) == 0 )
203         {
204                 body.s= NULL;
205                 body.len= 0;
206         }       
207         else
208         {
209                 body.s=get_body(msg);
210                 if (body.s== NULL) 
211                 {
212                         LM_ERR("cannot extract body from msg\n");
213                         goto error;
214                 }
215                 body.len = get_content_length( msg );
216         }
217
218         /* treat the two cases: event= presence & event=presence.winfo */       
219         if(event_flag & PRESENCE_EVENT)
220         {       
221                 LM_DBG("PRESENCE\n");
222                 hdr = msg->headers;
223                 while (hdr!= NULL)
224                 {
225                         if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0)
226                                 break;
227                         hdr = hdr->next;
228                 }
229                 if(hdr && strncmp(hdr->body.s,"terminated", 10)== 0)
230                 {
231                         /* chack if reason timeout => don't send notification */
232                         if(strncmp(hdr->body.s+11,"reason=timeout", 14)== 0)
233                         {
234                                 LM_DBG("Received Notification with state"
235                                         "terminated; reason= timeout=> don't send notification\n");
236                                 return 1;
237                         }       
238                         is_terminated= 1;
239
240                 }
241         
242                 if(build_xmpp_content(&to_uri, &from_uri, &body, &id, is_terminated)< 0)
243                 {
244                         LM_ERR("in function build_xmpp_content\n");     
245                         goto error;
246                 }
247         }       
248         else
249         {       
250                 if(event_flag & PWINFO_EVENT)
251                 {
252                         LM_DBG("PRESENCE.WINFO\n");
253                         hdr = msg->headers;
254                         while (hdr!= NULL)
255                         {
256                                 if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0)
257                                         break;
258                                 hdr = hdr->next;
259                         }
260                         if(hdr && strncmp(hdr->body.s,"terminated", 10)== 0)
261                         {
262                                 LM_DBG("Notify for presence.winfo with" 
263                                         " Subscription-State terminated- should not translate\n");
264                                 goto error;
265                         }
266                         if(winfo2xmpp(&to_uri, &body, &id)< 0)
267                         {
268                                 LM_ERR("while sending subscription\n");
269                                 goto error;
270                         }
271
272                 }
273                 else
274                 {
275                         LM_ERR("Missing or unsupported event header field value\n");
276                         goto error;
277                 }
278
279         }
280         free_to_params(&TO);
281         return 1;
282
283 error:
284         free_to_params(&TO);
285         return 0;
286 }
287
288 int build_xmpp_content(str* to_uri, str* from_uri, str* body, str* id,
289                 int is_terminated)
290 {
291         xmlDocPtr sip_doc= NULL;
292         xmlDocPtr doc= NULL;
293         xmlNodePtr xmpp_root= NULL;
294         xmlNodePtr sip_root= NULL;
295         xmlNodePtr new_node= NULL;
296         xmlNodePtr node = NULL;
297         xmlBufferPtr buffer= NULL;
298         xmlAttrPtr attr= NULL;
299         char* basic= NULL, *priority= NULL, *note= NULL;
300         str xmpp_msg;
301
302         LM_DBG("start...\n");
303
304         /* creating the xml doc for the xmpp message*/
305         doc= xmlNewDoc(0);
306         if(doc== NULL)
307         {
308                 LM_ERR("when creating new xml doc\n");
309                 goto error;
310         }
311         xmpp_root = xmlNewNode(NULL, BAD_CAST "presence");
312         if(xmpp_root==0)
313         {
314                 LM_ERR("when adding new node- presence\n");
315                 goto error;
316         }
317         xmlDocSetRootElement(doc, xmpp_root);
318
319         attr= xmlNewProp(xmpp_root, BAD_CAST "to", BAD_CAST to_uri->s);
320         if(attr== NULL)
321         {
322                 LM_ERR("while adding new attribute\n");
323                 goto error;
324         }
325         attr= xmlNewProp(xmpp_root, BAD_CAST "from", BAD_CAST from_uri->s);
326         if(attr== NULL)
327         {
328                 LM_ERR("while adding new attribute\n");
329                 goto error;
330         }
331         if(is_terminated)
332         {       
333                 attr=  xmlNewProp(xmpp_root, BAD_CAST "type", BAD_CAST "unsubscribed");
334                 if(attr== NULL)
335                 {
336                         LM_ERR("while adding new attribute\n");
337                         goto error;
338                 }
339                 goto done;
340         }
341         if(body->s== NULL)
342         {
343                 attr=  xmlNewProp(xmpp_root, BAD_CAST "type", BAD_CAST "unavailable");
344                 if(attr== NULL)
345                 {
346                         LM_ERR("while adding new attribute\n");
347                         goto error;
348                 }
349                 goto done;
350         }
351
352         /*extractiong the information from the sip message body*/
353         sip_doc= xmlParseMemory(body->s, body->len);
354         if(sip_doc== NULL)
355         {
356                 LM_ERR("while parsing xml memory\n");
357                 return -1;
358         }
359         sip_root= XMLDocGetNodeByName(sip_doc, "presence", NULL);
360         if(sip_root== NULL)
361         {
362                 LM_ERR("while extracting 'presence' node\n");
363                 goto error;
364         }
365         
366         node = XMLNodeGetNodeByName(sip_root, "basic", NULL);
367         if(node== NULL)
368         {
369                 LM_ERR("while extracting status basic node\n");
370                 goto error;
371         }
372         basic= (char*)xmlNodeGetContent(node);
373         if(basic== NULL)
374         {
375                 LM_ERR("while extracting status basic node content\n");
376                 goto error;
377         }
378         if(xmlStrcasecmp( (unsigned char*)basic,(unsigned char*) "closed")==0 )
379         {
380                 attr= xmlNewProp(xmpp_root, BAD_CAST "type", BAD_CAST "unavailable");
381                 if(attr== NULL)
382                 {
383                         LM_ERR("while adding node attr\n");
384                         xmlFree(basic);
385                         goto error;
386                 }
387                 xmlFree(basic);
388                 goto done;
389         }/* else the status is open so no type attr should be added */
390
391         xmlFree(basic);
392         /* addind show node */
393         node= XMLNodeGetNodeByName(sip_root, "note", NULL);
394         if(node== NULL)
395         {
396                 LM_DBG("No note node found\n");
397                 node= XMLNodeGetNodeByName(sip_root, "person", NULL);
398                 if(node== NULL)
399                 {
400                         LM_DBG("No person node found\n");
401                         goto done;
402                 }
403                 node= XMLNodeGetNodeByName(node, "note", NULL);
404                 if(node== NULL)
405                 {       
406                         LM_DBG("Person node has no note node\n");
407                         goto done;
408                 }       
409         }       
410         note= (char*)xmlNodeGetContent(node);
411         if(note== NULL)
412         {
413                 LM_ERR("while extracting note node content\n");
414                 goto error;
415         }
416
417         if((xmlStrcasecmp((unsigned char*)note, (unsigned char*)"away")== 0)||
418                         (xmlStrcasecmp((unsigned char*)note, (unsigned char*)"On the phone")== 0))
419         {
420                 new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show",
421                                 BAD_CAST "away");
422                 if(new_node== NULL)
423                 {
424                         LM_ERR("while adding node show: away\n");
425                         goto error;
426                 }       
427         }
428         else
429                 if(xmlStrcasecmp((unsigned char*)note, (unsigned char*)"busy")== 0)
430                 {
431                         new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show"
432                                         , BAD_CAST "xa");
433                         if(new_node== NULL)
434                         {
435                                 LM_ERR("while adding node show: away\n");
436                                 goto error;
437                         }       
438                 }
439
440                 /*
441                 if(xmlStrcasecmp((unsigned char*)note, (unsigned char*)"on the phone")== 0)
442                 {
443                         new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show", BAD_CAST "chat");
444                         if(new_node== NULL)
445                         {
446                                 LM_ERR("while adding node show: chat\n");
447                                 goto error;
448                         }       
449                 }
450                 else 
451                         if(xmlStrcasecmp((unsigned char*)note, (unsigned char*)"idle")== 0)
452                         {
453                                 new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show", BAD_CAST "idle");
454                                 if(new_node== NULL)
455                                 {
456                                         LM_ERR("while adding node: idle\n");
457                                         goto error;
458                                 }       
459                         }*/
460                         else
461                                 if((xmlStrcasecmp((unsigned char*)note,
462                                         (unsigned char*)"dnd")== 0)||
463                                         (xmlStrcasecmp((unsigned char*)note,
464                                                 (unsigned char*)"do not disturb")== 0)||
465                                         (xmlStrcasecmp((unsigned char*)note,
466                                         (unsigned char*)"Busy (DND)")== 0))
467                                 {
468                                         new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show",
469                                                         BAD_CAST "dnd");
470                                         if(new_node== NULL)
471                                         {
472                                                 LM_ERR("while adding node show: dnd\n");
473                                                 goto error;
474                                         }               
475                                 }
476                                 else
477                                         LM_DBG("Not Found Status\n");
478
479         
480         /* adding status node */
481         new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "status", BAD_CAST note);
482         if(new_node== NULL)
483         {
484                 LM_ERR("while adding node status\n");
485                 goto error;
486         }       
487         
488         xmlFree(note);
489         note= NULL;
490
491         /* adding priotity node*/
492         node= XMLNodeGetNodeByName(sip_root, "contact", NULL);
493         if(node== NULL)
494         {
495                 LM_DBG("No contact node found\n");
496         }
497         else
498         {
499                 priority= XMLNodeGetAttrContentByName(node, "priority");
500                 if(priority== NULL)
501                         LM_DBG("No priority attribute found\n");
502                 else
503                 {
504                         new_node= xmlNewChild(xmpp_root, NULL, BAD_CAST "priority",
505                                         BAD_CAST priority);
506                         if(sip_root== NULL)
507                         {
508                                 LM_ERR("while adding node\n");
509                                 xmlFree(priority);
510                                 goto error;
511                         }
512                         xmlFree(priority);
513                 }
514         }
515
516 done:
517         buffer= xmlBufferCreate();
518         if(buffer== NULL)
519         {
520                 LM_ERR("while adding creating new buffer\n");
521                 goto error;
522         }
523         
524         xmpp_msg.len= xmlNodeDump(buffer, doc, xmpp_root, 1,1);
525         if(xmpp_msg.len== -1)
526         {
527                 LM_ERR("while dumping node\n");
528                 goto error;
529         }
530         xmpp_msg.s= (char*)xmlBufferContent( buffer);
531         if(xmpp_msg.s==  NULL)
532         {
533                 LM_ERR("while extracting buffer content\n");
534                 goto error;
535         }
536         
537         LM_DBG("xmpp_msg: %.*s\n",xmpp_msg.len, xmpp_msg.s);
538         if( xmpp_notify(from_uri, to_uri, &xmpp_msg, id)< 0)
539         {
540                 LM_ERR("while sending xmpp_notify\n");
541                 goto error;
542         }
543
544         xmlBufferFree(buffer);
545         xmlCleanupParser();
546         xmlMemoryDump();
547
548         if(sip_doc)
549                 xmlFreeDoc(sip_doc);
550         if(doc)
551                 xmlFreeDoc(doc);
552         return 0;
553
554 error:
555         if(sip_doc)
556                 xmlFreeDoc(sip_doc);
557         if(note)
558                 xmlFree(note);
559         if(buffer)
560                 xmlBufferFree(buffer);
561         xmlCleanupParser();
562         xmlMemoryDump();
563
564         return -1;
565
566 }
567
568
569 int winfo2xmpp(str* to_uri, str* body, str* id)
570 {
571         xmlAttrPtr attr= NULL;
572         str xmpp_msg;
573         char* watcher= NULL ;
574         str from_uri;
575         xmlDocPtr notify_doc= NULL;
576         xmlDocPtr doc= NULL;
577         xmlNodePtr pidf_root= NULL;
578         xmlNodePtr root_node= NULL;
579         xmlNodePtr node= NULL;
580         xmlBufferPtr buffer= NULL;
581
582         LM_DBG("start...\n");
583         notify_doc= xmlParseMemory(body->s, body->len);
584         if(notify_doc== NULL)
585         {
586                 LM_ERR("while parsing xml memory\n");
587                 return -1;
588         }
589         pidf_root= XMLDocGetNodeByName(notify_doc, "watcherinfo", NULL);
590         if(pidf_root== NULL)
591         {
592                 LM_ERR("while extracting 'presence' node\n");
593                 goto error;
594         }
595         
596         node = XMLNodeGetNodeByName(pidf_root, "watcher", NULL);
597
598         for (; node!=NULL; node = node->next)
599         {               
600                 if( xmlStrcasecmp(node->name,(unsigned char*)"watcher"))
601                         continue;
602
603                 watcher= (char*)xmlNodeGetContent(node->children);      
604                 if(watcher== NULL)
605                 {
606                         LM_ERR("while extracting watcher node content\n");
607                         goto error;
608                 }
609                 from_uri.s= euri_sip_xmpp(watcher);
610                 if(from_uri.s== NULL)
611                 {
612                         LM_ERR("while encoding sip uri in xmpp\n");
613                         goto error;
614                 }       
615                 from_uri.len= strlen(from_uri.s);
616                 xmlFree(watcher);
617                 watcher= NULL;
618
619                 doc= xmlNewDoc( 0 );
620                 if(doc== NULL)
621                 {
622                         LM_ERR("when creating new xml doc\n");
623                         goto error;
624                 }
625                 root_node = xmlNewNode(NULL, BAD_CAST "presence");
626                 if(root_node== NULL)
627                 {
628                         LM_ERR("when adding new node\n");
629                         goto error;
630                 }
631                 xmlDocSetRootElement(doc, root_node);
632
633                 attr= xmlNewProp(root_node, BAD_CAST "to", BAD_CAST to_uri->s);
634                 if(attr== NULL)
635                 {
636                         LM_ERR("while adding attribute to_uri\n");
637                         goto error;
638                 }
639                 attr= xmlNewProp(root_node, BAD_CAST "from", BAD_CAST from_uri.s);
640                 if(attr== NULL)
641                 {
642                         LM_ERR("while adding attribute from_uri\n");
643                         goto error;
644                 }
645                 attr= xmlNewProp(root_node, BAD_CAST "type", BAD_CAST "subscribe");
646                 if(attr== NULL)
647                 {
648                         LM_ERR("while adding attribute type\n");
649                         goto error;
650                 }
651                 buffer= xmlBufferCreate();
652                 if(buffer== NULL)
653                 {
654                         LM_ERR("while adding creating new buffer\n");
655                         goto error;
656                 }
657                 
658                 xmpp_msg.len= xmlNodeDump(buffer, doc, root_node, 1,1);
659                 if(xmpp_msg.len== -1)
660                 {
661                         LM_ERR("while dumping node\n");
662                         goto error;
663                 }
664                 xmpp_msg.s= (char*)xmlBufferContent( buffer);
665                 if(xmpp_msg.s==  NULL)
666                 {
667                         LM_ERR("while extracting buffer content\n");
668                         goto error;
669                 }
670         
671                 LM_DBG("xmpp_msg: %.*s\n",xmpp_msg.len, xmpp_msg.s);
672                 
673                 if( xmpp_subscribe(&from_uri, to_uri, &xmpp_msg, id)< 0)
674                 {
675                         LM_ERR("while sending xmpp_subscribe\n");
676                         goto error;
677                 }
678                 xmlBufferFree(buffer);
679                 buffer= NULL;
680                 xmlFreeDoc(doc);
681                 doc= NULL;
682         }
683
684         xmlFreeDoc(notify_doc);
685         xmlCleanupParser();
686         xmlMemoryDump();
687         return 0;
688
689 error:
690
691         if(doc)
692                 xmlFreeDoc(doc);
693         if(notify_doc)
694                 xmlFreeDoc(notify_doc);
695         if(watcher)
696                 xmlFree(watcher);
697         if(buffer)
698                 xmlBufferFree(buffer);
699         xmlCleanupParser();
700         xmlMemoryDump();
701
702         return -1;
703
704 }
705
706 char* get_error_reason(int code, str* reason)
707 {
708         char* err_cond= NULL;
709
710         err_cond= (char*)pkg_malloc(50* sizeof(char));
711         if(err_cond== NULL)
712         {
713                 LM_ERR("no more memory\n");
714                 return NULL;
715         }
716         
717         switch( code )
718         {
719                 case 300:       { strcpy(err_cond, "redirect");                         break;}
720                 case 301:       { strcpy(err_cond, "gone");                             break;}
721                 case 302:       { strcpy(err_cond, "redirect");                         break;}
722                 case 305:       { strcpy(err_cond, "redirect");                         break;}
723                 case 380:       { strcpy(err_cond, "not-acceptable");                   break;}
724                 case 400:       { strcpy(err_cond, "bad-request");                      break;}
725                 case 401:       { strcpy(err_cond, "not-authorized");                   break;}
726                 case 402:       { strcpy(err_cond, "payment-required");                 break;}
727                 case 403:       { strcpy(err_cond, "forbidden");                        break;}
728                 case 404:       { strcpy(err_cond, "item-not-found");                   break;}
729                 case 405:       { strcpy(err_cond, "not-allowed");                      break;}
730                 case 406:       { strcpy(err_cond, "not-acceptable");                   break;}
731                 case 407:       { strcpy(err_cond, "registration-required");            break;}
732                 case 408:       { strcpy(err_cond, "service-unavailable");              break;}
733                 case 410:       { strcpy(err_cond, "gone");                             break;}
734                 case 413:       { strcpy(err_cond, "bad-request");                      break;}
735                 case 414:       { strcpy(err_cond, "bad-request");                      break;}
736                 case 415:       { strcpy(err_cond, "bad-request");                      break;}
737                 case 416:       { strcpy(err_cond, "bad-request");                      break;}
738                 case 420:       { strcpy(err_cond, "bad-request");                      break;}
739                 case 421:       { strcpy(err_cond, "bad-request");                      break;}
740                 case 423:       { strcpy(err_cond, "bad-request");                      break;}
741                 case 480:       { strcpy(err_cond, "recipient-unavailable");            break;}
742                 case 481:       { strcpy(err_cond, "item-not-found");                   break;}
743                 case 482:       { strcpy(err_cond, "not-acceptable");                   break;}
744                 case 483:       { strcpy(err_cond, "not-acceptable");                   break;}
745                 case 484:       { strcpy(err_cond, "jid-malformed");                    break;}
746                 case 485:       { strcpy(err_cond, "item-not-found");                   break;}
747                 case 488:       { strcpy(err_cond, "not-acceptable");                   break;}
748                 case 491:       { strcpy(err_cond, "unexpected-request");               break;}
749                 case 500:       { strcpy(err_cond, "internal-server-error");            break;}
750                 case 501:       { strcpy(err_cond, "feature-not-implemented");          break;}
751                 case 502:       { strcpy(err_cond, "remote-server-not-found");          break;}
752                 case 503:       { strcpy(err_cond, "service-unavailable");              break;}
753                 case 504:       { strcpy(err_cond, "remote-server-timeout");            break;}
754                 case 505:       { strcpy(err_cond, "not-acceptable");                   break;}
755                 case 513:       { strcpy(err_cond, "bad-request");                      break;}
756                 case 600:       { strcpy(err_cond, "service-unavailable");              break;}
757                 case 603:       { strcpy(err_cond, "service-unavailable");              break;}
758                 case 604:       { strcpy(err_cond, "item-not-found");                   break;}
759                 case 606:       { strcpy(err_cond, "not-acceptable");                   break;}
760                 default:        { strcpy(err_cond, "not-acceptable");                   break;}
761         }
762
763         return err_cond;
764 }       
765
766
767 int Sipreply2Xmpp(ua_pres_t* hentity, struct sip_msg * msg) 
768 {
769         char* uri;
770         /* named according to the direction of the message in xmpp*/
771         str from_uri;
772         str to_uri;
773         xmlDocPtr doc= NULL;
774         xmlNodePtr root_node= NULL, node = NULL;
775         xmlAttrPtr attr= NULL;
776         str xmpp_msg;
777         int code;
778         str reason;
779         char* err_reason= NULL;
780         xmlBufferPtr buffer= NULL;
781         
782         LM_DBG("start..\n");
783         uri=(char*)pkg_malloc(sizeof(char)*( hentity->watcher_uri->len+1));
784         if(uri== NULL)
785         {
786                 LM_ERR("no more memory\n");
787                 goto error;
788         }
789         memcpy(uri, hentity->watcher_uri->s, hentity->watcher_uri->len);
790         uri[hentity->watcher_uri->len]= '\0';
791         to_uri.s= duri_sip_xmpp(uri);
792         if(to_uri.s== NULL)
793         {
794                 LM_ERR("whil decoding sip uri in xmpp\n");
795                 pkg_free(uri);
796                 goto error;     
797         }       
798
799         to_uri.len= strlen(to_uri.s);
800         pkg_free(uri);
801         
802         uri=(char*)pkg_malloc(sizeof(char)*( hentity->pres_uri->len+1));
803         if(uri== NULL)
804         {
805                 LM_ERR("no more memory\n");
806                 goto error;
807         }
808         memcpy(uri, hentity->pres_uri->s, hentity->pres_uri->len);
809         uri[hentity->pres_uri->len]= '\0';
810         from_uri.s= euri_sip_xmpp(uri);
811         if(from_uri.s== NULL)
812         {
813                 LM_ERR("while encoding sip uri in xmpp\n");
814                 pkg_free(uri);
815                 goto error;
816         }
817
818         from_uri.len= strlen(from_uri.s);
819         pkg_free(uri);
820
821         doc= xmlNewDoc(BAD_CAST "1.0");
822         if(doc==0)
823                 goto error;
824         root_node = xmlNewNode(NULL, BAD_CAST "presence");
825         
826         if(root_node==0)
827                 goto error;
828         xmlDocSetRootElement(doc, root_node);
829
830         attr= xmlNewProp(root_node, BAD_CAST "to", BAD_CAST to_uri.s);
831         if(attr== NULL)
832         {
833                 LM_ERR("while adding attribute to\n");
834                 goto error;
835         }
836         attr= xmlNewProp(root_node, BAD_CAST "from", BAD_CAST from_uri.s);
837         if(attr== NULL)
838         {
839                 LM_ERR("while adding attribute from\n");
840                 goto error;
841         }
842
843         if(msg== FAKED_REPLY)
844         {
845                 code = 408;
846                 reason.s= "Request Timeout";
847                 reason.len= strlen(reason.s)- 1;
848         }
849         else
850         {
851                 code= msg->first_line.u.reply.statuscode;
852                 reason= msg->first_line.u.reply.reason;
853         }
854
855         LM_DBG(" to_uri= %s\n\t from_uri= %s\n",
856                         to_uri.s, from_uri.s);
857
858         if(code>=300)
859         {
860                 LM_DBG(" error code(>= 300)\n");
861                 err_reason= get_error_reason(code, &reason);
862                 if(err_reason== NULL)
863                 {
864                         LM_ERR("couldn't get response phrase\n");
865                         goto error;
866                 }
867         
868                 attr= xmlNewProp(root_node, BAD_CAST "type", BAD_CAST "error");
869                 if(attr== NULL)
870                 {
871                         LM_ERR("while adding new attribute\n");
872                         goto error;
873                 }
874                 node= xmlNewChild(root_node, 0, BAD_CAST  "error", 0 );
875                 if(node== NULL)
876                 {
877                         LM_ERR("while adding new node\n");
878                         goto error;
879                 }       
880                 node= xmlNewChild(node, 0,  BAD_CAST err_reason, 0 );
881                 if(node== NULL)
882                 {
883                         LM_ERR("while adding new node\n");
884                         goto error;
885                 }       
886
887                 attr= xmlNewProp(node, BAD_CAST "xmlns", 
888                                 BAD_CAST "urn:ietf:params:xml:ns:xmpp-stanzas");
889                 if(attr== NULL)
890                 {
891                         LM_ERR("while adding new attribute\n");
892                         goto error;
893                 }
894
895         }
896         else
897                 if(code>=200 )
898                 {
899                         LM_DBG(" 2xx code\n");
900                         attr= xmlNewProp(root_node, BAD_CAST "type", BAD_CAST "subscribed");
901                         if(attr== NULL)
902                         {
903                                 LM_ERR("while adding new attribute\n");
904                                 goto error;
905                         }
906                 }
907
908                 buffer= xmlBufferCreate();
909                 if(buffer== NULL)
910                 {
911                         LM_ERR("while adding creating new buffer\n");
912                         goto error;
913                 }
914                 
915                 xmpp_msg.len= xmlNodeDump(buffer, doc, root_node, 1,1);
916                 if(xmpp_msg.len== -1)
917                 {
918                         LM_ERR("while dumping node\n");
919                         goto error;
920                 }
921                 xmpp_msg.s= (char*)xmlBufferContent( buffer);
922                 if(xmpp_msg.s==  NULL)
923                 {
924                         LM_ERR("while extracting buffer content\n");
925                         goto error;
926                 }
927         
928
929         LM_DBG("xmpp_msg: %.*s\n",xmpp_msg.len, xmpp_msg.s);
930         
931         if(xmpp_packet(&from_uri, &to_uri, &xmpp_msg, &hentity->to_tag)< 0)
932         {
933                 LM_ERR("while sending xmpp_reply_to_subscribe\n");
934                 goto error;
935         }
936         if(err_reason)
937                 pkg_free(err_reason);
938         xmlFreeDoc(doc);
939         
940         return 0;
941
942 error:
943
944         if(doc)
945                 xmlFreeDoc(doc);
946         if(err_reason)
947                 pkg_free(err_reason);
948         return -1;
949
950 }
951