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 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_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
573 osip_message_set_contact(msg,identity);
574 add_presence_body(msg,status);
575 eXosip_insubscription_send_request(op->did,msg);
576 }else ms_error("could not create notify for incoming subscription.");
581 int sal_notify_close(SalOp *op){
582 osip_message_t *msg=NULL;
584 eXosip_insubscription_build_notify(op->did,EXOSIP_SUBCRSTATE_TERMINATED,DEACTIVATED,&msg);
586 const char *identity=sal_op_get_contact(op);
587 if (identity==NULL) identity=sal_op_get_to(op);
588 osip_message_set_contact(msg,identity);
589 add_presence_body(msg,SalPresenceOffline);
590 eXosip_insubscription_send_request(op->did,msg);
591 }else ms_error("sal_notify_close(): could not create notify for incoming subscription"
592 " did=%i, nid=%i",op->did,op->nid);
597 int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus presence_mode){
602 mk_presence_body (presence_mode, from, buf, sizeof (buf), presence_style);
604 i = eXosip_build_publish(&pub,from, to, NULL, "presence", "300",
605 presence_style ? "application/xpidf+xml" : "application/pidf+xml", buf);
607 ms_warning("Failed to build publish request.");
612 i = eXosip_publish(pub, to); /* should update the sip-if-match parameter
613 from sip-etag from last 200ok of PUBLISH */
616 ms_message("Failed to send publish request.");
619 sal_add_other(sal_op_get_sal(op),op,pub);
623 static void _sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){
624 SalOp *op=sal_op_new(sal);
629 osip_from_to_str(ev->request->from,&tmp);
630 sal_op_set_from(op,tmp);
632 osip_from_to_str(ev->request->to,&tmp);
633 sal_op_set_to(op,tmp);
635 sal_add_in_subscribe(sal,op,ev->request);
636 sal->callbacks.subscribe_received(op,sal_op_get_from(op));
639 void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){
640 /*workaround a bug in eXosip: incoming SUBSCRIBES within dialog with expires: 0 are
641 recognized as new incoming subscribes*/
642 SalOp *op=sal_find_in_subscribe_by_call_id(sal,ev->request->call_id);
645 osip_message_header_get_byname(ev->request,"expires",0,&h);
646 if (h && h->hvalue && atoi(h->hvalue)==0){
647 ms_warning("This susbscribe is not a new one but terminates an old one.");
650 sal_exosip_subscription_closed(sal,ev);
652 osip_message_t *msg=NULL;
653 ms_warning("Probably a refresh subscribe");
655 eXosip_insubscription_build_answer(ev->tid,202,&msg);
656 eXosip_insubscription_send_answer(ev->tid,202,msg);
659 }else _sal_exosip_subscription_recv(sal,ev);
662 void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){
663 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
665 osip_from_t *from=NULL;
666 osip_body_t *body=NULL;
667 SalPresenceStatus estatus=SalPresenceOffline;
669 ms_message("Receiving notify with sid=%i,nid=%i",ev->sid,ev->nid);
672 ms_error("No operation related to this notify !");
675 if (ev->request==NULL) return;
677 from=ev->request->from;
678 osip_message_get_body(ev->request,0,&body);
680 ms_error("No body in NOTIFY");
683 osip_from_to_str(from,&tmp);
684 if (strstr(body->body,"pending")!=NULL){
685 estatus=SalPresenceOffline;
686 }else if (strstr(body->body,"busy")!=NULL){
687 estatus=SalPresenceBusy;
688 }else if (strstr(body->body,"berightback")!=NULL
689 || strstr(body->body,"in-transit")!=NULL ){
690 estatus=SalPresenceBerightback;
691 }else if (strstr(body->body,"away")!=NULL
692 || strstr(body->body,"idle")){
693 estatus=SalPresenceAway;
694 }else if (strstr(body->body,"onthephone")!=NULL
695 || strstr(body->body,"on-the-phone")!=NULL){
696 estatus=SalPresenceOnthephone;
697 }else if (strstr(body->body,"outtolunch")!=NULL
698 || strstr(body->body,"meal")!=NULL){
699 estatus=SalPresenceOuttolunch;
700 }else if (strstr(body->body,"closed")!=NULL){
701 estatus=SalPresenceOffline;
702 }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) {
703 estatus=SalPresenceOnline;
705 estatus=SalPresenceOffline;
707 ms_message("We are notified that %s has online status %i",tmp,estatus);
708 if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) {
709 sal_remove_out_subscribe(sal,op);
712 ms_message("And outgoing subscription terminated by remote.");
714 sal->callbacks.notify_presence(op,op->sid!=-1 ? SalSubscribeActive : SalSubscribeTerminated, estatus,NULL);
716 /* try to detect presence message style used by server,
717 * and switch our presence messages to servers style */
718 if (strstr (body->body, "//IETF//DTD RFCxxxx XPIDF 1.0//EN") != NULL) {
719 presence_style = RFCxxxx;
720 } else if (strstr(body->body,"http://schemas.microsoft.com/2002/09/sip/presence")!=NULL) {
721 presence_style = MSOLDPRES;
727 void sal_exosip_subscription_answered(Sal *sal,eXosip_event_t *ev){
728 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
730 ms_error("Subscription answered but no associated op !");
736 void sal_exosip_in_subscription_closed(Sal *sal, eXosip_event_t *ev){
737 SalOp *op=sal_find_in_subscribe(sal,ev->nid);
740 ms_error("Incoming subscription closed but no associated op !");
745 sal_remove_in_subscribe(sal,op);
749 osip_from_to_str(ev->request->from,&tmp);
750 sal->callbacks.subscribe_closed(op,tmp);
755 void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev){
756 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
758 ms_error("Subscription closed but no associated op !");
761 sal_remove_out_subscribe(sal,op);
764 sal->callbacks.notify_presence(op,SalSubscribeTerminated, SalPresenceOffline,NULL);