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;
42 ms_message("No op for sid %i",sid);
46 static void sal_add_out_subscribe(Sal *sal, SalOp *op){
47 sal->out_subscribes=ms_list_append(sal->out_subscribes,op);
50 void sal_remove_out_subscribe(Sal *sal, SalOp *op){
51 sal->out_subscribes=ms_list_remove(sal->out_subscribes,op);
54 SalOp * sal_find_in_subscribe(Sal *sal, int nid){
57 for(elem=sal->in_subscribes;elem!=NULL;elem=elem->next){
58 op=(SalOp*)elem->data;
59 if (op->nid==nid) return op;
64 static SalOp * sal_find_in_subscribe_by_call_id(Sal *sal, osip_call_id_t *call_id){
67 for(elem=sal->in_subscribes;elem!=NULL;elem=elem->next){
68 op=(SalOp*)elem->data;
69 if (op->call_id && osip_call_id_match(op->call_id,call_id)==0)
75 static void sal_add_in_subscribe(Sal *sal, SalOp *op, osip_message_t *subs){
76 osip_call_id_clone(subs->call_id,&op->call_id);
77 sal->in_subscribes=ms_list_append(sal->in_subscribes,op);
80 void sal_remove_in_subscribe(Sal *sal, SalOp *op){
81 sal->in_subscribes=ms_list_remove(sal->in_subscribes,op);
84 int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
85 osip_message_t *sip=NULL;
89 /* we are not currently in communication with the destination */
91 sal_op_set_from(op,from);
95 sal_exosip_fix_route(op);
97 eXosip_message_build_request(&sip,"MESSAGE",sal_op_get_to(op),
98 sal_op_get_from(op),sal_op_get_route(op));
100 osip_message_set_content_type(sip,"text/plain");
101 osip_message_set_body(sip,msg,strlen(msg));
102 sal_add_other(op->base.root,op,sip);
103 eXosip_message_send_request(sip);
105 ms_error("Could not build MESSAGE request !");
111 /* we are currently in communication with the destination */
113 //First we generate an INFO message to get the current call_id and a good cseq
114 eXosip_call_build_request(op->did,"MESSAGE",&sip);
117 ms_warning("could not get a build info to send MESSAGE, maybe no previous call established ?");
121 osip_message_set_content_type(sip,"text/plain");
122 osip_message_set_body(sip,msg,strlen(msg));
123 eXosip_call_send_request(op->did,sip);
129 /*presence Subscribe/notify*/
130 int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
131 osip_message_t *msg=NULL;
133 sal_op_set_from(op,from);
135 sal_op_set_to(op,to);
136 sal_exosip_fix_route(op);
138 eXosip_subscribe_build_initial_request(&msg,sal_op_get_to(op),sal_op_get_from(op),
139 sal_op_get_route(op),"presence",600);
141 ms_error("Could not build subscribe request to %s",to);
145 if (op->base.contact){
146 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
147 osip_message_set_contact(msg,op->base.contact);
149 op->sid=eXosip_subscribe_send_initial_request(msg);
152 osip_message_free(msg);
155 sal_add_out_subscribe(op->base.root,op);
159 int sal_unsubscribe(SalOp *op){
160 osip_message_t *msg=NULL;
162 ms_error("cannot unsubscribe, no dialog !");
166 eXosip_subscribe_build_refresh_request(op->did,&msg);
168 osip_message_set_expires(msg,"0");
169 eXosip_subscribe_send_refresh_request(op->did,msg);
170 }else ms_error("Could not build subscribe refresh request ! op->sid=%i, op->did=%i",
176 int sal_subscribe_accept(SalOp *op){
177 osip_message_t *msg=NULL;
179 eXosip_insubscription_build_answer(op->tid,202,&msg);
181 ms_error("Fail to build answer to subscribe.");
185 if (op->base.contact){
186 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
187 osip_message_set_contact(msg,op->base.contact);
189 eXosip_insubscription_send_answer(op->tid,202,msg);
194 int sal_subscribe_decline(SalOp *op){
196 eXosip_insubscription_send_answer(op->tid,401,NULL);
201 static void mk_presence_body (const SalPresenceStatus online_status, const char *contact_info,
202 char *buf, size_t buflen, presence_type_t ptype) {
205 /* definition from http://msdn.microsoft.com/en-us/library/cc246202%28PROT.10%29.aspx */
208 if (online_status==SalPresenceOnline)
210 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
211 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
213 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
215 <address uri=\"%s\" priority=\"0.800000\">\n\
216 <status status=\"open\" />\n\
217 <msnsubstatus substatus=\"online\" />\n\
220 </presence>", contact_info, atom_id, contact_info);
223 else if (online_status == SalPresenceBusy ||
224 online_status == SalPresenceDonotdisturb)
226 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
227 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
229 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
231 <address uri=\"%s\" priority=\"0.800000\">\n\
232 <status status=\"inuse\" />\n\
233 <msnsubstatus substatus=\"busy\" />\n\
235 </atom>\n</presence>", contact_info, atom_id, contact_info);
238 else if (online_status==SalPresenceBerightback)
240 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
241 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
243 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
245 <address uri=\"%s\" priority=\"0.800000\">\n\
246 <status status=\"open\" />\n\
247 <msnsubstatus substatus=\"berightback\" />\n\
250 </presence>", contact_info, atom_id, contact_info);
253 else if (online_status == SalPresenceAway ||
254 online_status == SalPresenceMoved)
256 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
257 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
259 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
261 <address uri=\"%s\" priority=\"0.800000\">\n\
262 <status status=\"open\" />\n\
263 <msnsubstatus substatus=\"away\" />\n\
266 </presence>", contact_info, atom_id, contact_info);
269 else if (online_status==SalPresenceOnthephone)
271 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
272 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
274 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
276 <address uri=\"%s\" priority=\"0.800000\">\n\
277 <status status=\"inuse\" />\n\
278 <msnsubstatus substatus=\"onthephone\" />\n\
281 </presence>", contact_info, atom_id, contact_info);
284 else if (online_status==SalPresenceOuttolunch)
286 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
287 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
289 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
291 <address uri=\"%s\" priority=\"0.800000\">\n\
292 <status status=\"open\" />\n\
293 <msnsubstatus substatus=\"outtolunch\" />\n\
296 </presence>", contact_info, atom_id, contact_info);
301 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
302 <!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
304 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
306 <address uri=\"%s\" priority=\"0.800000\">\n\
307 <status status=\"closed\" />\n\
308 <msnsubstatus substatus=\"away\" />\n\
311 </presence>", contact_info, atom_id, contact_info);
316 /* Couldn't find schema http://schemas.microsoft.com/2002/09/sip/presence
317 * so messages format has been taken from Communigate that can send notify
318 * requests with this schema
322 if (online_status==SalPresenceOnline)
324 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
325 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
327 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
329 <address uri=\"%s\">\n\
330 <status status=\"open\" />\n\
331 <msnsubstatus substatus=\"online\" />\n\
334 </presence>", contact_info, atom_id, contact_info);
337 else if (online_status == SalPresenceBusy ||
338 online_status == SalPresenceDonotdisturb)
340 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
341 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
343 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
345 <address uri=\"%s\">\n\
346 <status status=\"inuse\" />\n\
347 <msnsubstatus substatus=\"busy\" />\n\
349 </atom>\n</presence>", contact_info, atom_id, contact_info);
352 else if (online_status==SalPresenceBerightback)
354 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
355 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
357 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
359 <address uri=\"%s\">\n\
360 <status status=\"inactive\" />\n\
361 <msnsubstatus substatus=\"berightback\" />\n\
364 </presence>", contact_info, atom_id, contact_info);
367 else if (online_status == SalPresenceAway ||
368 online_status == SalPresenceMoved)
370 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
371 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
373 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
375 <address uri=\"%s\">\n\
376 <status status=\"inactive\" />\n\
377 <msnsubstatus substatus=\"idle\" />\n\
380 </presence>", contact_info, atom_id, contact_info);
383 else if (online_status==SalPresenceOnthephone)
385 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
386 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
388 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
390 <address uri=\"%s\">\n\
391 <status status=\"inuse\" />\n\
392 <msnsubstatus substatus=\"onthephone\" />\n\
395 </presence>", contact_info, atom_id, contact_info);
398 else if (online_status==SalPresenceOuttolunch)
400 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
401 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
403 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
405 <address uri=\"%s\">\n\
406 <status status=\"inactive\" />\n\
407 <msnsubstatus substatus=\"outtolunch\" />\n\
410 </presence>", contact_info, atom_id, contact_info);
415 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
416 <!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
418 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
420 <address uri=\"%s\">\n\
421 <status status=\"closed\" />\n\
422 <msnsubstatus substatus=\"offline\" />\n\
425 </presence>", contact_info, atom_id, contact_info);
429 default: { /* use pidf+xml as default format, rfc4479, rfc4480, rfc3863 */
431 if (online_status==SalPresenceOnline)
433 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
434 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
435 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
436 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
438 <tuple id=\"sg89ae\">\n\
439 <status><basic>open</basic></status>\n\
440 <contact priority=\"0.8\">%s</contact>\n\
443 contact_info, contact_info);
445 else if (online_status == SalPresenceBusy ||
446 online_status == SalPresenceDonotdisturb)
448 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
449 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
450 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
451 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
453 <tuple id=\"sg89ae\">\n\
454 <status><basic>open</basic></status>\n\
455 <contact priority=\"0.8\">%s</contact>\n\
457 <dm:person id=\"sg89aep\">\n\
458 <rpid:activities><rpid:busy/></rpid:activities>\n\
461 contact_info, contact_info);
463 else if (online_status==SalPresenceBerightback)
465 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
466 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
467 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
468 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
470 <tuple id=\"sg89ae\">\n\
471 <status><basic>open</basic></status>\n\
472 <contact priority=\"0.8\">%s</contact>\n\
474 <dm:person id=\"sg89aep\">\n\
475 <rpid:activities><rpid:in-transit/></rpid:activities>\n\
478 contact_info, contact_info);
480 else if (online_status == SalPresenceAway ||
481 online_status == SalPresenceMoved)
483 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
484 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
485 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
486 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
488 <tuple id=\"sg89ae\">\n\
489 <status><basic>open</basic></status>\n\
490 <contact priority=\"0.8\">%s</contact>\n\
492 <dm:person id=\"sg89aep\">\n\
493 <rpid:activities><rpid:away/></rpid:activities>\n\
496 contact_info, contact_info);
498 else if (online_status==SalPresenceOnthephone)
500 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
501 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
502 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
503 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
505 <tuple id=\"sg89ae\">\n\
506 <status><basic>open</basic></status>\n\
507 <contact priority=\"0.8\">%s</contact>\n\
509 <dm:person id=\"sg89aep\">\n\
510 <rpid:activities><rpid:on-the-phone/></rpid:activities>\n\
513 contact_info, contact_info);
515 else if (online_status==SalPresenceOuttolunch)
517 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
518 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
519 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
520 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
522 <tuple id=\"7777\">\n\
523 <status><basic>open</basic></status>\n\
524 <contact priority=\"0.8\">%s</contact>\n\
526 <dm:person id=\"78787878\">\n\
527 <rpid:activities><rpid:meal/></rpid:activities>\n\
528 <rpid:note>Out to lunch</rpid:note> \n\
531 contact_info, contact_info);
535 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
536 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
537 xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
538 xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
540 <tuple id=\"sg89ae\">\n\
541 <status><basic>closed</basic></status>\n\
542 <contact priority=\"0.8\">%s</contact>\n\
544 </presence>\n", contact_info, contact_info);
552 static void add_presence_body(osip_message_t *notify, SalPresenceStatus online_status)
557 osip_from_t *from=NULL;
558 from=osip_message_get_from(notify);
559 osip_uri_to_str(from->url,&contact_info);
561 mk_presence_body (online_status, contact_info, buf, sizeof (buf), presence_style);
563 osip_message_set_body(notify, buf, strlen(buf));
564 osip_message_set_content_type(notify,
565 presence_style ? "application/xpidf+xml" : "application/pidf+xml");
567 osip_free(contact_info);
571 int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message){
572 osip_message_t *msg=NULL;
573 eXosip_ss_t ss=EXOSIP_SUBCRSTATE_ACTIVE;
575 ms_warning("Cannot notify, subscription was closed.");
580 eXosip_insubscription_build_notify(op->did,ss,DEACTIVATED,&msg);
582 const char *identity=sal_op_get_contact(op);
583 if (identity==NULL) identity=sal_op_get_to(op);
584 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
585 osip_message_set_contact(msg,identity);
586 add_presence_body(msg,status);
587 eXosip_insubscription_send_request(op->did,msg);
588 }else ms_error("could not create notify for incoming subscription.");
593 int sal_notify_close(SalOp *op){
594 osip_message_t *msg=NULL;
596 eXosip_insubscription_build_notify(op->did,EXOSIP_SUBCRSTATE_TERMINATED,DEACTIVATED,&msg);
598 const char *identity=sal_op_get_contact(op);
599 if (identity==NULL) identity=sal_op_get_to(op);
600 osip_message_set_contact(msg,identity);
601 add_presence_body(msg,SalPresenceOffline);
602 eXosip_insubscription_send_request(op->did,msg);
603 }else ms_error("sal_notify_close(): could not create notify for incoming subscription"
604 " did=%i, nid=%i",op->did,op->nid);
609 int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus presence_mode){
614 mk_presence_body (presence_mode, from, buf, sizeof (buf), presence_style);
616 i = eXosip_build_publish(&pub,from, to, NULL, "presence", "300",
617 presence_style ? "application/xpidf+xml" : "application/pidf+xml", buf);
619 ms_warning("Failed to build publish request.");
624 i = eXosip_publish(pub, to); /* should update the sip-if-match parameter
625 from sip-etag from last 200ok of PUBLISH */
628 ms_message("Failed to send publish request.");
631 sal_add_other(sal_op_get_sal(op),op,pub);
635 static void _sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){
636 SalOp *op=sal_op_new(sal);
641 osip_from_to_str(ev->request->from,&tmp);
642 sal_op_set_from(op,tmp);
644 osip_from_to_str(ev->request->to,&tmp);
645 sal_op_set_to(op,tmp);
647 sal_add_in_subscribe(sal,op,ev->request);
648 sal->callbacks.subscribe_received(op,sal_op_get_from(op));
651 void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){
652 /*workaround a bug in eXosip: incoming SUBSCRIBES within dialog with expires: 0 are
653 recognized as new incoming subscribes*/
654 SalOp *op=sal_find_in_subscribe_by_call_id(sal,ev->request->call_id);
657 osip_message_header_get_byname(ev->request,"expires",0,&h);
658 if (h && h->hvalue && atoi(h->hvalue)==0){
659 ms_warning("This susbscribe is not a new one but terminates an old one.");
662 sal_exosip_subscription_closed(sal,ev);
664 osip_message_t *msg=NULL;
665 ms_warning("Probably a refresh subscribe");
667 eXosip_insubscription_build_answer(ev->tid,202,&msg);
668 eXosip_insubscription_send_answer(ev->tid,202,msg);
671 }else _sal_exosip_subscription_recv(sal,ev);
674 void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){
675 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
677 osip_from_t *from=NULL;
678 osip_body_t *body=NULL;
679 SalPresenceStatus estatus=SalPresenceOffline;
681 ms_message("Receiving notify with sid=%i,nid=%i",ev->sid,ev->nid);
684 ms_error("No operation related to this notify !");
687 if (ev->request==NULL) return;
689 from=ev->request->from;
690 osip_message_get_body(ev->request,0,&body);
692 ms_error("No body in NOTIFY");
695 osip_from_to_str(from,&tmp);
696 if (strstr(body->body,"pending")!=NULL){
697 estatus=SalPresenceOffline;
698 }else if (strstr(body->body,"busy")!=NULL){
699 estatus=SalPresenceBusy;
700 }else if (strstr(body->body,"berightback")!=NULL
701 || strstr(body->body,"in-transit")!=NULL ){
702 estatus=SalPresenceBerightback;
703 }else if (strstr(body->body,"away")!=NULL
704 || strstr(body->body,"idle")){
705 estatus=SalPresenceAway;
706 }else if (strstr(body->body,"onthephone")!=NULL
707 || strstr(body->body,"on-the-phone")!=NULL){
708 estatus=SalPresenceOnthephone;
709 }else if (strstr(body->body,"outtolunch")!=NULL
710 || strstr(body->body,"meal")!=NULL){
711 estatus=SalPresenceOuttolunch;
712 }else if (strstr(body->body,"closed")!=NULL){
713 estatus=SalPresenceOffline;
714 }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) {
715 estatus=SalPresenceOnline;
717 estatus=SalPresenceOffline;
719 ms_message("We are notified that %s has online status %i",tmp,estatus);
720 if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) {
721 sal_remove_out_subscribe(sal,op);
724 ms_message("And outgoing subscription terminated by remote.");
726 sal->callbacks.notify_presence(op,op->sid!=-1 ? SalSubscribeActive : SalSubscribeTerminated, estatus,NULL);
728 /* try to detect presence message style used by server,
729 * and switch our presence messages to servers style */
730 if (strstr (body->body, "//IETF//DTD RFCxxxx XPIDF 1.0//EN") != NULL) {
731 presence_style = RFCxxxx;
732 } else if (strstr(body->body,"http://schemas.microsoft.com/2002/09/sip/presence")!=NULL) {
733 presence_style = MSOLDPRES;
739 void sal_exosip_subscription_answered(Sal *sal,eXosip_event_t *ev){
740 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
742 ms_error("Subscription answered but no associated op !");
748 void sal_exosip_in_subscription_closed(Sal *sal, eXosip_event_t *ev){
749 SalOp *op=sal_find_in_subscribe(sal,ev->nid);
752 ms_error("Incoming subscription closed but no associated op !");
757 sal_remove_in_subscribe(sal,op);
761 osip_from_to_str(ev->request->from,&tmp);
762 sal->callbacks.subscribe_closed(op,tmp);
767 void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev){
768 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
770 ms_error("Subscription closed but no associated op !");
773 sal_remove_out_subscribe(sal,op);
776 sal->callbacks.notify_presence(op,SalSubscribeTerminated, SalPresenceOffline,NULL);