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_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg, const char *t){
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 sal_exosip_add_custom_headers(sip,op->base.custom_headers);
101 osip_message_set_date(sip,t);
102 osip_message_set_content_type(sip,content_type);
103 if (msg) osip_message_set_body(sip,msg,strlen(msg));
104 sal_add_other(op->base.root,op,sip);
105 eXosip_message_send_request(sip);
107 ms_error("Could not build MESSAGE request !");
113 /* we are currently in communication with the destination */
115 //First we generate an INFO message to get the current call_id and a good cseq
116 eXosip_call_build_request(op->did,"MESSAGE",&sip);
119 ms_warning("could not get a build info to send MESSAGE, maybe no previous call established ?");
123 osip_message_set_content_type(sip,content_type);
124 if (msg) osip_message_set_body(sip,msg,strlen(msg));
125 eXosip_call_send_request(op->did,sip);
131 int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg,const char *t) {
132 return sal_message_send(op,from,to,"text/plain",msg,t);
134 /*presence Subscribe/notify*/
135 int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
136 osip_message_t *msg=NULL;
138 sal_op_set_from(op,from);
140 sal_op_set_to(op,to);
141 sal_exosip_fix_route(op);
143 eXosip_subscribe_build_initial_request(&msg,sal_op_get_to(op),sal_op_get_from(op),
144 sal_op_get_route(op),"presence",600);
146 ms_error("Could not build subscribe request to %s",to);
150 if (op->base.contact){
151 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
152 osip_message_set_contact(msg,op->base.contact);
154 op->sid=eXosip_subscribe_send_initial_request(msg);
157 osip_message_free(msg);
160 sal_add_out_subscribe(op->base.root,op);
164 int sal_unsubscribe(SalOp *op){
165 osip_message_t *msg=NULL;
167 ms_error("cannot unsubscribe, no dialog !");
171 eXosip_subscribe_build_refresh_request(op->did,&msg);
173 osip_message_set_expires(msg,"0");
174 eXosip_subscribe_send_refresh_request(op->did,msg);
175 }else ms_error("Could not build subscribe refresh request ! op->sid=%i, op->did=%i",
181 int sal_subscribe_accept(SalOp *op){
182 osip_message_t *msg=NULL;
184 eXosip_insubscription_build_answer(op->tid,202,&msg);
186 ms_error("Fail to build answer to subscribe.");
190 if (op->base.contact){
191 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
192 osip_message_set_contact(msg,op->base.contact);
194 eXosip_insubscription_send_answer(op->tid,202,msg);
199 int sal_subscribe_decline(SalOp *op){
201 eXosip_insubscription_send_answer(op->tid,401,NULL);
206 static void mk_presence_body (const SalPresenceStatus online_status, const char *contact_info,
207 char *buf, size_t buflen, presence_type_t ptype) {
210 /* definition from http://msdn.microsoft.com/en-us/library/cc246202%28PROT.10%29.aspx */
213 if (online_status==SalPresenceOnline)
215 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
216 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
218 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
220 "<address uri=\"%s\" priority=\"0.800000\">\n"
221 "<status status=\"open\" />\n"
222 "<msnsubstatus substatus=\"online\" />\n"
225 "</presence>", contact_info, atom_id, contact_info);
228 else if (online_status == SalPresenceBusy ||
229 online_status == SalPresenceDonotdisturb)
231 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
232 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
234 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
236 "<address uri=\"%s\" priority=\"0.800000\">\n"
237 "<status status=\"inuse\" />\n"
238 "<msnsubstatus substatus=\"busy\" />\n"
240 "</atom>\n</presence>", contact_info, atom_id, contact_info);
243 else if (online_status==SalPresenceBerightback)
245 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
246 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
248 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
250 "<address uri=\"%s\" priority=\"0.800000\">\n"
251 "<status status=\"open\" />\n"
252 "<msnsubstatus substatus=\"berightback\" />\n"
255 "</presence>", contact_info, atom_id, contact_info);
258 else if (online_status == SalPresenceAway ||
259 online_status == SalPresenceMoved)
261 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
262 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
264 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
266 "<address uri=\"%s\" priority=\"0.800000\">\n"
267 "<status status=\"open\" />\n"
268 "<msnsubstatus substatus=\"away\" />\n"
271 "</presence>", contact_info, atom_id, contact_info);
274 else if (online_status==SalPresenceOnthephone)
276 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
277 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
279 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
281 "<address uri=\"%s\" priority=\"0.800000\">\n"
282 "<status status=\"inuse\" />\n"
283 "<msnsubstatus substatus=\"onthephone\" />\n"
286 "</presence>", contact_info, atom_id, contact_info);
289 else if (online_status==SalPresenceOuttolunch)
291 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
292 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
294 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
296 "<address uri=\"%s\" priority=\"0.800000\">\n"
297 "<status status=\"open\" />\n"
298 "<msnsubstatus substatus=\"outtolunch\" />\n"
301 "</presence>", contact_info, atom_id, contact_info);
306 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
307 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
309 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
311 "<address uri=\"%s\" priority=\"0.800000\">\n"
312 "<status status=\"closed\" />\n"
313 "<msnsubstatus substatus=\"away\" />\n"
316 "</presence>", contact_info, atom_id, contact_info);
321 /* Couldn't find schema http://schemas.microsoft.com/2002/09/sip/presence
322 * so messages format has been taken from Communigate that can send notify
323 * requests with this schema
327 if (online_status==SalPresenceOnline)
329 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
330 "<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
332 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
334 "<address uri=\"%s\">\n"
335 "<status status=\"open\" />\n"
336 "<msnsubstatus substatus=\"online\" />\n"
339 "</presence>", contact_info, atom_id, contact_info);
342 else if (online_status == SalPresenceBusy ||
343 online_status == SalPresenceDonotdisturb)
345 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
346 "<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
348 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
350 "<address uri=\"%s\">\n"
351 "<status status=\"inuse\" />\n"
352 "<msnsubstatus substatus=\"busy\" />\n"
354 "</atom>\n</presence>", contact_info, atom_id, contact_info);
357 else if (online_status==SalPresenceBerightback)
359 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
360 "<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
362 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
364 "<address uri=\"%s\">\n"
365 "<status status=\"inactive\" />\n"
366 "<msnsubstatus substatus=\"berightback\" />\n"
369 "</presence>", contact_info, atom_id, contact_info);
372 else if (online_status == SalPresenceAway ||
373 online_status == SalPresenceMoved)
375 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
376 "<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
378 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
380 "<address uri=\"%s\">\n"
381 "<status status=\"inactive\" />\n"
382 "<msnsubstatus substatus=\"idle\" />\n"
385 "</presence>", contact_info, atom_id, contact_info);
388 else if (online_status==SalPresenceOnthephone)
390 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
391 "<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
393 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
395 "<address uri=\"%s\">\n"
396 "<status status=\"inuse\" />\n"
397 "<msnsubstatus substatus=\"onthephone\" />\n"
400 "</presence>", contact_info, atom_id, contact_info);
403 else if (online_status==SalPresenceOuttolunch)
405 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
406 "<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
408 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
410 "<address uri=\"%s\">\n"
411 "<status status=\"inactive\" />\n"
412 "<msnsubstatus substatus=\"outtolunch\" />\n"
415 "</presence>", contact_info, atom_id, contact_info);
420 snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
421 "<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
423 "<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
425 "<address uri=\"%s\">\n"
426 "<status status=\"closed\" />\n"
427 "<msnsubstatus substatus=\"offline\" />\n"
430 "</presence>", contact_info, atom_id, contact_info);
434 default: { /* use pidf+xml as default format, rfc4479, rfc4480, rfc3863 */
436 if (online_status==SalPresenceOnline)
438 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
439 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
440 "xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
441 "xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
443 "<tuple id=\"sg89ae\">\n"
444 "<status><basic>open</basic></status>\n"
445 "<contact priority=\"0.8\">%s</contact>\n"
448 contact_info, contact_info);
450 else if (online_status == SalPresenceBusy ||
451 online_status == SalPresenceDonotdisturb)
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:busy/></rpid:activities>\n"
466 contact_info, contact_info);
468 else if (online_status==SalPresenceBerightback)
470 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
471 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
472 "xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
473 "xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
475 "<tuple id=\"sg89ae\">\n"
476 "<status><basic>open</basic></status>\n"
477 "<contact priority=\"0.8\">%s</contact>\n"
479 "<dm:person id=\"sg89aep\">\n"
480 "<rpid:activities><rpid:in-transit/></rpid:activities>\n"
483 contact_info, contact_info);
485 else if (online_status == SalPresenceAway ||
486 online_status == SalPresenceMoved)
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:away/></rpid:activities>\n"
501 contact_info, contact_info);
503 else if (online_status==SalPresenceOnthephone)
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=\"sg89ae\">\n"
511 "<status><basic>open</basic></status>\n"
512 "<contact priority=\"0.8\">%s</contact>\n"
514 "<dm:person id=\"sg89aep\">\n"
515 "<rpid:activities><rpid:on-the-phone/></rpid:activities>\n"
518 contact_info, contact_info);
520 else if (online_status==SalPresenceOuttolunch)
522 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
523 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
524 "xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
525 "xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
527 "<tuple id=\"7777\">\n"
528 "<status><basic>open</basic></status>\n"
529 "<contact priority=\"0.8\">%s</contact>\n"
531 "<dm:person id=\"78787878\">\n"
532 "<rpid:activities><rpid:meal/></rpid:activities>\n"
533 "<rpid:note>Out to lunch</rpid:note> \n"
536 contact_info, contact_info);
540 snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
541 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
542 "xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
543 "xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
545 "<tuple id=\"sg89ae\">\n"
546 "<status><basic>closed</basic></status>\n"
547 "<contact priority=\"0.8\">%s</contact>\n"
549 "</presence>\n", contact_info, contact_info);
557 static void add_presence_body(osip_message_t *notify, SalPresenceStatus online_status)
562 osip_from_t *from=NULL;
563 from=osip_message_get_from(notify);
564 osip_uri_to_str(from->url,&contact_info);
566 mk_presence_body (online_status, contact_info, buf, sizeof (buf), presence_style);
568 osip_message_set_body(notify, buf, strlen(buf));
569 osip_message_set_content_type(notify,
570 presence_style ? "application/xpidf+xml" : "application/pidf+xml");
572 osip_free(contact_info);
576 int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message){
577 osip_message_t *msg=NULL;
578 eXosip_ss_t ss=EXOSIP_SUBCRSTATE_ACTIVE;
580 ms_warning("Cannot notify, subscription was closed.");
585 eXosip_insubscription_build_notify(op->did,ss,DEACTIVATED,&msg);
587 const char *identity=sal_op_get_contact(op);
588 if (identity==NULL) identity=sal_op_get_to(op);
589 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
590 osip_message_set_contact(msg,identity);
591 add_presence_body(msg,status);
592 eXosip_insubscription_send_request(op->did,msg);
593 }else ms_error("could not create notify for incoming subscription.");
598 int sal_notify_close(SalOp *op){
599 osip_message_t *msg=NULL;
601 eXosip_insubscription_build_notify(op->did,EXOSIP_SUBCRSTATE_TERMINATED,DEACTIVATED,&msg);
603 const char *identity=sal_op_get_contact(op);
604 if (identity==NULL) identity=sal_op_get_to(op);
605 osip_message_set_contact(msg,identity);
606 add_presence_body(msg,SalPresenceOffline);
607 eXosip_insubscription_send_request(op->did,msg);
608 }else ms_error("sal_notify_close(): could not create notify for incoming subscription"
609 " did=%i, nid=%i",op->did,op->nid);
614 int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus presence_mode){
619 mk_presence_body (presence_mode, from, buf, sizeof (buf), presence_style);
621 i = eXosip_build_publish(&pub,from, to, NULL, "presence", "300",
622 presence_style ? "application/xpidf+xml" : "application/pidf+xml", buf);
624 ms_warning("Failed to build publish request.");
629 i = eXosip_publish(pub, to); /* should update the sip-if-match parameter
630 from sip-etag from last 200ok of PUBLISH */
633 ms_message("Failed to send publish request.");
636 sal_add_other(sal_op_get_sal(op),op,pub);
640 static void _sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){
641 SalOp *op=sal_op_new(sal);
646 osip_from_to_str(ev->request->from,&tmp);
647 sal_op_set_from(op,tmp);
649 osip_from_to_str(ev->request->to,&tmp);
650 sal_op_set_to(op,tmp);
652 sal_add_in_subscribe(sal,op,ev->request);
653 sal->callbacks.subscribe_received(op,sal_op_get_from(op));
656 void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){
657 /*workaround a bug in eXosip: incoming SUBSCRIBES within dialog with expires: 0 are
658 recognized as new incoming subscribes*/
659 SalOp *op=sal_find_in_subscribe_by_call_id(sal,ev->request->call_id);
662 osip_message_header_get_byname(ev->request,"expires",0,&h);
663 if (h && h->hvalue && atoi(h->hvalue)==0){
664 ms_warning("This susbscribe is not a new one but terminates an old one.");
667 sal_exosip_subscription_closed(sal,ev);
669 osip_message_t *msg=NULL;
670 ms_warning("Probably a refresh subscribe");
672 eXosip_insubscription_build_answer(ev->tid,202,&msg);
673 eXosip_insubscription_send_answer(ev->tid,202,msg);
676 }else _sal_exosip_subscription_recv(sal,ev);
679 void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){
680 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
682 osip_from_t *from=NULL;
683 osip_body_t *body=NULL;
684 SalPresenceStatus estatus=SalPresenceOffline;
686 ms_message("Receiving notify with sid=%i,nid=%i",ev->sid,ev->nid);
689 ms_error("No operation related to this notify !");
692 if (ev->request==NULL) return;
694 from=ev->request->from;
695 osip_message_get_body(ev->request,0,&body);
697 ms_error("No body in NOTIFY");
700 osip_from_to_str(from,&tmp);
701 if (strstr(body->body,"pending")!=NULL){
702 estatus=SalPresenceOffline;
703 }else if (strstr(body->body,"busy")!=NULL){
704 estatus=SalPresenceBusy;
705 }else if (strstr(body->body,"berightback")!=NULL
706 || strstr(body->body,"in-transit")!=NULL ){
707 estatus=SalPresenceBerightback;
708 }else if (strstr(body->body,"away")!=NULL
709 || strstr(body->body,"idle")){
710 estatus=SalPresenceAway;
711 }else if (strstr(body->body,"onthephone")!=NULL
712 || strstr(body->body,"on-the-phone")!=NULL){
713 estatus=SalPresenceOnthephone;
714 }else if (strstr(body->body,"outtolunch")!=NULL
715 || strstr(body->body,"meal")!=NULL){
716 estatus=SalPresenceOuttolunch;
717 }else if (strstr(body->body,"closed")!=NULL){
718 estatus=SalPresenceOffline;
719 }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) {
720 estatus=SalPresenceOnline;
722 estatus=SalPresenceOffline;
724 ms_message("We are notified that %s has online status %i",tmp,estatus);
725 if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) {
726 sal_remove_out_subscribe(sal,op);
729 ms_message("And outgoing subscription terminated by remote.");
731 sal->callbacks.notify_presence(op,op->sid!=-1 ? SalSubscribeActive : SalSubscribeTerminated, estatus,NULL);
733 /* try to detect presence message style used by server,
734 * and switch our presence messages to servers style */
735 if (strstr (body->body, "//IETF//DTD RFCxxxx XPIDF 1.0//EN") != NULL) {
736 presence_style = RFCxxxx;
737 } else if (strstr(body->body,"http://schemas.microsoft.com/2002/09/sip/presence")!=NULL) {
738 presence_style = MSOLDPRES;
744 void sal_exosip_subscription_answered(Sal *sal,eXosip_event_t *ev){
745 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
747 ms_error("Subscription answered but no associated op !");
753 void sal_exosip_in_subscription_closed(Sal *sal, eXosip_event_t *ev){
754 SalOp *op=sal_find_in_subscribe(sal,ev->nid);
757 ms_error("Incoming subscription closed but no associated op !");
762 sal_remove_in_subscribe(sal,op);
766 osip_from_to_str(ev->request->from,&tmp);
767 sal->callbacks.subscribe_closed(op,tmp);
772 void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev){
773 SalOp *op=sal_find_out_subscribe(sal,ev->sid);
775 ms_error("Subscription closed but no associated op !");
778 sal_remove_out_subscribe(sal,op);
781 sal->callbacks.notify_presence(op,SalSubscribeTerminated, SalPresenceOffline,NULL);