3 Copyright (C) 2010 Simon MORLAT (simon.morlat@free.fr)
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "sal_eXosip2.h"
30 * REVISIT: this static variable forces every dialog to use the same presence description type depending
31 * on what is received on a single dialog...
33 static presence_type_t presence_style = PIDF;
35 SalOp * sal_find_out_subscribe(Sal *sal, int sid){
38 for(elem=sal->out_subscribes;elem!=NULL;elem=elem->next){
39 op=(SalOp*)elem->data;
40 if (op->sid==sid) return op;
45 static void sal_add_out_subscribe(Sal *sal, SalOp *op){
46 sal->out_subscribes=ms_list_append(sal->out_subscribes,op);
49 void sal_remove_out_subscribe(Sal *sal, SalOp *op){
50 sal->out_subscribes=ms_list_remove(sal->out_subscribes,op);
53 static SalOp * sal_find_in_subscribe(Sal *sal, int nid){
56 for(elem=sal->in_subscribes;elem!=NULL;elem=elem->next){
57 op=(SalOp*)elem->data;
58 if (op->nid==nid) return op;
63 static SalOp * sal_find_in_subscribe_by_call_id(Sal *sal, osip_call_id_t *call_id){
66 for(elem=sal->in_subscribes;elem!=NULL;elem=elem->next){
67 op=(SalOp*)elem->data;
68 if (op->call_id && osip_call_id_match(op->call_id,call_id)==0)
74 static void sal_add_in_subscribe(Sal *sal, SalOp *op, osip_message_t *subs){
75 osip_call_id_clone(subs->call_id,&op->call_id);
76 sal->in_subscribes=ms_list_append(sal->in_subscribes,op);
79 void sal_remove_in_subscribe(Sal *sal, SalOp *op){
80 sal->in_subscribes=ms_list_remove(sal->in_subscribes,op);
83 int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
84 osip_message_t *sip=NULL;
88 /* we are not currently in communication with the destination */
90 sal_op_set_from(op,from);
95 eXosip_message_build_request(&sip,"MESSAGE",sal_op_get_to(op),
96 sal_op_get_from(op),sal_op_get_route(op));
98 osip_message_set_content_type(sip,"text/plain");
99 osip_message_set_body(sip,msg,strlen(msg));
100 sal_add_other(op->base.root,op,sip);
101 eXosip_message_send_request(sip);
103 ms_error("Could not build MESSAGE request !");
109 /* we are currently in communication with the destination */
111 //First we generate an INFO message to get the current call_id and a good cseq
112 eXosip_call_build_request(op->did,"MESSAGE",&sip);
115 ms_warning("could not get a build info to send MESSAGE, maybe no previous call established ?");
119 osip_message_set_content_type(sip,"text/plain");
120 osip_message_set_body(sip,msg,strlen(msg));
121 eXosip_call_send_request(op->did,sip);
127 /*presence Subscribe/notify*/
128 int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
131 sal_op_set_from(op,from);
133 sal_op_set_to(op,to);
134 sal_exosip_fix_route(op);
136 eXosip_subscribe_build_initial_request(&msg,sal_op_get_to(op),sal_op_get_from(op),
137 sal_op_get_route(op),"presence",600);
138 if (op->base.contact){
139 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
140 osip_message_set_contact(msg,op->base.contact);
142 op->sid=eXosip_subscribe_send_initial_request(msg);
145 osip_message_free(msg);
148 sal_add_out_subscribe(op->base.root,op);
152 int sal_unsubscribe(SalOp *op){
153 osip_message_t *msg=NULL;
155 ms_error("cannot unsubscribe, no dialog !");
159 eXosip_subscribe_build_refresh_request(op->did,&msg);
161 osip_message_set_expires(msg,"0");
162 eXosip_subscribe_send_refresh_request(op->did,msg);
163 }else ms_error("Could not build subscribe refresh request ! op->sid=%i, op->did=%i",
169 int sal_subscribe_accept(SalOp *op){
172 eXosip_insubscription_build_answer(op->tid,202,&msg);
173 if (op->base.contact){
174 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
175 osip_message_set_contact(msg,op->base.contact);
177 eXosip_insubscription_send_answer(op->tid,202,msg);
182 int sal_subscribe_decline(SalOp *op){
184 eXosip_insubscription_send_answer(op->tid,401,NULL);
189 static void mk_presence_body (const SalPresenceStatus online_status, const char *contact_info,
190 char *buf, size_t buflen, presence_type_t ptype) {
193 /* definition from http://msdn.microsoft.com/en-us/library/cc246202%28PROT.10%29.aspx */
196 if (online_status==SalPresenceOnline)
198 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
199 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
201 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
203 <address uri=\"%s\" priority=\"0.800000\">\n\
204 <status status=\"open\" />\n\
205 <msnsubstatus substatus=\"online\" />\n\
208 </presence>", contact_info, atom_id, contact_info);
211 else if (online_status == SalPresenceBusy ||
212 online_status == SalPresenceDonotdisturb)
214 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
215 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
217 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
219 <address uri=\"%s\" priority=\"0.800000\">\n\
220 <status status=\"inuse\" />\n\
221 <msnsubstatus substatus=\"busy\" />\n\
223 </atom>\n</presence>", contact_info, atom_id, contact_info);
226 else if (online_status==SalPresenceBerightback)
228 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
229 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
231 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
233 <address uri=\"%s\" priority=\"0.800000\">\n\
234 <status status=\"open\" />\n\
235 <msnsubstatus substatus=\"berightback\" />\n\
238 </presence>", contact_info, atom_id, contact_info);
241 else if (online_status == SalPresenceAway ||
242 online_status == SalPresenceMoved)
244 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
245 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
247 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
249 <address uri=\"%s\" priority=\"0.800000\">\n\
250 <status status=\"open\" />\n\
251 <msnsubstatus substatus=\"away\" />\n\
254 </presence>", contact_info, atom_id, contact_info);
257 else if (online_status==SalPresenceOnthephone)
259 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
260 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
262 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
264 <address uri=\"%s\" priority=\"0.800000\">\n\
265 <status status=\"inuse\" />\n\
266 <msnsubstatus substatus=\"onthephone\" />\n\
269 </presence>", contact_info, atom_id, contact_info);
272 else if (online_status==SalPresenceOuttolunch)
274 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
275 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
277 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
279 <address uri=\"%s\" priority=\"0.800000\">\n\
280 <status status=\"open\" />\n\
281 <msnsubstatus substatus=\"outtolunch\" />\n\
284 </presence>", contact_info, atom_id, contact_info);
289 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
290 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
292 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
294 <address uri=\"%s\" priority=\"0.800000\">\n\
295 <status status=\"closed\" />\n\
296 <msnsubstatus substatus=\"away\" />\n\
299 </presence>", contact_info, atom_id, contact_info);
304 /* Couldn't find schema http://schemas.microsoft.com/2002/09/sip/presence
305 * so messages format has been taken from Communigate that can send notify
306 * requests with this schema
310 if (online_status==SalPresenceOnline)
312 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
313 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
315 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
317 <address uri=\"%s\">\n\
318 <status status=\"open\" />\n\
319 <msnsubstatus substatus=\"online\" />\n\
322 </presence>", contact_info, atom_id, contact_info);
325 else if (online_status == SalPresenceBusy ||
326 online_status == SalPresenceDonotdisturb)
328 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
329 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
331 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
333 <address uri=\"%s\">\n\
334 <status status=\"inuse\" />\n\
335 <msnsubstatus substatus=\"busy\" />\n\
337 </atom>\n</presence>", contact_info, atom_id, contact_info);
340 else if (online_status==SalPresenceBerightback)
342 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
343 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
345 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
347 <address uri=\"%s\">\n\
348 <status status=\"inactive\" />\n\
349 <msnsubstatus substatus=\"berightback\" />\n\
352 </presence>", contact_info, atom_id, contact_info);
355 else if (online_status == SalPresenceAway ||
356 online_status == SalPresenceMoved)
358 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
359 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
361 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
363 <address uri=\"%s\">\n\
364 <status status=\"inactive\" />\n\
365 <msnsubstatus substatus=\"idle\" />\n\
368 </presence>", contact_info, atom_id, contact_info);
371 else if (online_status==SalPresenceOnthephone)
373 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
374 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
376 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
378 <address uri=\"%s\">\n\
379 <status status=\"inuse\" />\n\
380 <msnsubstatus substatus=\"onthephone\" />\n\
383 </presence>", contact_info, atom_id, contact_info);
386 else if (online_status==SalPresenceOuttolunch)
388 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
389 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
391 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
393 <address uri=\"%s\">\n\
394 <status status=\"inactive\" />\n\
395 <msnsubstatus substatus=\"outtolunch\" />\n\
398 </presence>", contact_info, atom_id, contact_info);
403 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
404 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
406 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
408 <address uri=\"%s\">\n\
409 <status status=\"closed\" />\n\
410 <msnsubstatus substatus=\"offline\" />\n\
413 </presence>", contact_info, atom_id, contact_info);
417 default: { /* use pidf+xml as default format, rfc4479, rfc4480, rfc3863 */
419 if (online_status==SalPresenceOnline)
421 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
422 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
423 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
424 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
426 <tuple id=\"sg89ae\">\n\
427 <status><basic>open</basic></status>\n\
428 <contact priority=\"0.8\">%s</contact>\n\
431 contact_info, contact_info);
433 else if (online_status == SalPresenceBusy ||
434 online_status == SalPresenceDonotdisturb)
436 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
437 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
438 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
439 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
441 <tuple id=\"sg89ae\">\n\
442 <status><basic>open</basic></status>\n\
443 <contact priority=\"0.8\">%s</contact>\n\
445 <dm:person id=\"sg89aep\">\n\
446 <rpid:activities><rpid:busy/></rpid:activities>\n\
449 contact_info, contact_info);
451 else if (online_status==SalPresenceBerightback)
453 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
454 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
455 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
456 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
458 <tuple id=\"sg89ae\">\n\
459 <status><basic>open</basic></status>\n\
460 <contact priority=\"0.8\">%s</contact>\n\
462 <dm:person id=\"sg89aep\">\n\
463 <rpid:activities><rpid:in-transit/></rpid:activities>\n\
466 contact_info, contact_info);
468 else if (online_status == SalPresenceAway ||
469 online_status == SalPresenceMoved)
471 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
472 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
473 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
474 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
476 <tuple id=\"sg89ae\">\n\
477 <status><basic>open</basic></status>\n\
478 <contact priority=\"0.8\">%s</contact>\n\
480 <dm:person id=\"sg89aep\">\n\
481 <rpid:activities><rpid:away/></rpid:activities>\n\
484 contact_info, contact_info);
486 else if (online_status==SalPresenceOnthephone)
488 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
489 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
490 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
491 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
493 <tuple id=\"sg89ae\">\n\
494 <status><basic>open</basic></status>\n\
495 <contact priority=\"0.8\">%s</contact>\n\
497 <dm:person id=\"sg89aep\">\n\
498 <rpid:activities><rpid:on-the-phone/></rpid:activities>\n\
501 contact_info, contact_info);
503 else if (online_status==SalPresenceOuttolunch)
505 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
506 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
507 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
508 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
510 <tuple id=\"7777\">\n\
511 <status><basic>open</basic></status>\n\
512 <contact priority=\"0.8\">%s</contact>\n\
514 <dm:person id=\"78787878\">\n\
515 <rpid:activities><rpid:meal/></rpid:activities>\n\
516 <rpid:note>Out to lunch</rpid:note> \n\
519 contact_info, contact_info);
523 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
524 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
525 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
526 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
528 <tuple id=\"sg89ae\">\n\
529 <status><basic>closed</basic></status>\n\
530 <contact priority=\"0.8\">%s</contact>\n\
532 </presence>\n", contact_info, contact_info);
540 static void add_presence_body(osip_message_t *notify, SalPresenceStatus online_status)
545 osip_from_t *from=NULL;
546 from=osip_message_get_from(notify);
547 osip_uri_to_str(from->url,&contact_info);
549 mk_presence_body (online_status, contact_info, buf, sizeof (buf), presence_style);
551 osip_message_set_body(notify, buf, strlen(buf));
552 osip_message_set_content_type(notify,
553 presence_style ? "application/xpidf+xml" : "application/pidf+xml");
555 osip_free(contact_info);
559 int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message){
561 eXosip_ss_t ss=EXOSIP_SUBCRSTATE_ACTIVE;
563 ms_warning("Cannot notify, subscription was closed.");
568 eXosip_insubscription_build_notify(op->did,ss,DEACTIVATED,&msg);
570 const char *identity=sal_op_get_contact(op);
571 if (identity==NULL) identity=sal_op_get_to(op);
572 osip_message_set_contact(msg,identity);
573 add_presence_body(msg,status);
574 eXosip_insubscription_send_request(op->did,msg);
575 }else ms_error("could not create notify for incoming subscription.");
580 int sal_notify_close(SalOp *op){
581 osip_message_t *msg=NULL;
583 eXosip_insubscription_build_notify(op->did,EXOSIP_SUBCRSTATE_TERMINATED,DEACTIVATED,&msg);
585 const char *identity=sal_op_get_contact(op);
586 if (identity==NULL) identity=sal_op_get_to(op);
587 osip_message_set_contact(msg,identity);
588 add_presence_body(msg,SalPresenceOffline);
589 eXosip_insubscription_send_request(op->did,msg);
590 }else ms_error("sal_notify_close(): could not create notify for incoming subscription"
591 " did=%i, nid=%i",op->did,op->nid);
596 int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus presence_mode){
601 mk_presence_body (presence_mode, from, buf, sizeof (buf), presence_style);
603 i = eXosip_build_publish(&pub,from, to, NULL, "presence", "300",
604 presence_style ? "application/xpidf+xml" : "application/pidf+xml", buf);
606 ms_warning("Failed to build publish request.");
611 i = eXosip_publish(pub, to); /* should update the sip-if-match parameter
612 from sip-etag from last 200ok of PUBLISH */
615 ms_message("Failed to send publish request.");
618 sal_add_other(sal_op_get_sal(op),op,pub);
622 static void _sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){
623 SalOp *op=sal_op_new(sal);
628 osip_from_to_str(ev->request->from,&tmp);
629 sal_op_set_from(op,tmp);
631 osip_from_to_str(ev->request->to,&tmp);
632 sal_op_set_to(op,tmp);
634 sal_add_in_subscribe(sal,op,ev->request);
635 sal->callbacks.subscribe_received(op,sal_op_get_from(op));
638 void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){
639 /*workaround a bug in eXosip: incoming SUBSCRIBES within dialog with expires: 0 are
640 recognized as new incoming subscribes*/
641 SalOp *op=sal_find_in_subscribe_by_call_id(sal,ev->request->call_id);
644 osip_message_header_get_byname(ev->request,"expires",0,&h);
645 if (h && h->hvalue && atoi(h->hvalue)==0){
646 ms_warning("This susbscribe is not a new one but terminates an old one.");
649 sal_exosip_subscription_closed(sal,ev);
651 osip_message_t *msg=NULL;
652 ms_warning("Probably a refresh subscribe");
654 eXosip_insubscription_build_answer(ev->tid,202,&msg);
655 eXosip_insubscription_send_answer(ev->tid,202,msg);
658 }else _sal_exosip_subscription_recv(sal,ev);
661 void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){
662 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
664 osip_from_t *from=NULL;
665 osip_body_t *body=NULL;
666 SalPresenceStatus estatus=SalPresenceOffline;
668 ms_message("Receiving notify with sid=%i,nid=%i",ev->sid,ev->nid);
671 ms_error("No operation related to this notify !");
674 if (ev->request==NULL) return;
676 from=ev->request->from;
677 osip_message_get_body(ev->request,0,&body);
679 ms_error("No body in NOTIFY");
682 osip_from_to_str(from,&tmp);
683 if (strstr(body->body,"pending")!=NULL){
684 estatus=SalPresenceOffline;
685 }else if (strstr(body->body,"busy")!=NULL){
686 estatus=SalPresenceBusy;
687 }else if (strstr(body->body,"berightback")!=NULL
688 || strstr(body->body,"in-transit")!=NULL ){
689 estatus=SalPresenceBerightback;
690 }else if (strstr(body->body,"away")!=NULL
691 || strstr(body->body,"idle")){
692 estatus=SalPresenceAway;
693 }else if (strstr(body->body,"onthephone")!=NULL
694 || strstr(body->body,"on-the-phone")!=NULL){
695 estatus=SalPresenceOnthephone;
696 }else if (strstr(body->body,"outtolunch")!=NULL
697 || strstr(body->body,"meal")!=NULL){
698 estatus=SalPresenceOuttolunch;
699 }else if (strstr(body->body,"closed")!=NULL){
700 estatus=SalPresenceOffline;
701 }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) {
702 estatus=SalPresenceOnline;
704 estatus=SalPresenceOffline;
706 ms_message("We are notified that %s has online status %i",tmp,estatus);
707 if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) {
708 sal_remove_out_subscribe(sal,op);
711 ms_message("And outgoing subscription terminated by remote.");
713 sal->callbacks.notify_presence(op,op->sid!=-1 ? SalSubscribeActive : SalSubscribeTerminated, estatus,NULL);
715 /* try to detect presence message style used by server,
716 * and switch our presence messages to servers style */
717 if (strstr (body->body, "//IETF//DTD RFCxxxx XPIDF 1.0//EN") != NULL) {
718 presence_style = RFCxxxx;
719 } else if (strstr(body->body,"http://schemas.microsoft.com/2002/09/sip/presence")!=NULL) {
720 presence_style = MSOLDPRES;
726 void sal_exosip_subscription_answered(Sal *sal,eXosip_event_t *ev){
727 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
729 ms_error("Subscription answered but no associated op !");
735 void sal_exosip_in_subscription_closed(Sal *sal, eXosip_event_t *ev){
736 SalOp *op=sal_find_in_subscribe(sal,ev->nid);
739 ms_error("Incoming subscription closed but no associated op !");
744 sal_remove_in_subscribe(sal,op);
748 osip_from_to_str(ev->request->from,&tmp);
749 sal->callbacks.subscribe_closed(op,tmp);
754 void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev){
755 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
757 ms_error("Subscription closed but no associated op !");
760 sal_remove_out_subscribe(sal,op);
763 sal->callbacks.notify_presence(op,SalSubscribeTerminated, SalPresenceOffline,NULL);