]> sjero.net Git - linphone/blob - coreapi/sal_eXosip2_presence.c
fix bug causing double subscribe.
[linphone] / coreapi / sal_eXosip2_presence.c
1 /*
2 linphone
3 Copyright (C) 2010  Simon MORLAT (simon.morlat@free.fr)
4
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.
9
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.
14
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.
18 */
19
20
21 #include "sal_eXosip2.h"
22
23
24 static SalOp * sal_find_out_subscribe(Sal *sal, int sid){
25         const MSList *elem;
26         SalOp *op;
27         for(elem=sal->out_subscribes;elem!=NULL;elem=elem->next){
28                 op=(SalOp*)elem->data;
29                 if (op->sid==sid) return op;
30         }
31         return NULL;
32 }
33
34 static void sal_add_out_subscribe(Sal *sal, SalOp *op){
35         sal->out_subscribes=ms_list_append(sal->out_subscribes,op);
36 }
37
38 void sal_remove_out_subscribe(Sal *sal, SalOp *op){
39         sal->out_subscribes=ms_list_remove(sal->out_subscribes,op);
40 }
41
42 static SalOp * sal_find_in_subscribe(Sal *sal, int nid){
43         const MSList *elem;
44         SalOp *op;
45         for(elem=sal->in_subscribes;elem!=NULL;elem=elem->next){
46                 op=(SalOp*)elem->data;
47                 if (op->nid==nid) return op;
48         }
49         return NULL;
50 }
51
52 static void sal_add_in_subscribe(Sal *sal, SalOp *op){
53         sal->in_subscribes=ms_list_append(sal->in_subscribes,op);
54 }
55
56 void sal_remove_in_subscribe(Sal *sal, SalOp *op){
57         sal->in_subscribes=ms_list_remove(sal->in_subscribes,op);
58 }
59
60 int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
61         osip_message_t *sip=NULL;
62         if (from)
63                 sal_op_set_from(op,from);
64         if (to)
65                 sal_op_set_to(op,to);
66
67         eXosip_lock();
68         eXosip_message_build_request(&sip,"MESSAGE",sal_op_get_to(op),
69             sal_op_get_from(op),sal_op_get_route(op));
70         osip_message_set_content_type(sip,"text/plain");
71         osip_message_set_body(sip,msg,strlen(msg));
72         eXosip_message_send_request(sip);
73         eXosip_unlock();
74         return 0;
75 }
76
77 /*presence Subscribe/notify*/
78 int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
79         osip_message_t *msg;
80         if (from)
81                 sal_op_set_from(op,from);
82         if (to)
83                 sal_op_set_to(op,to);
84         sal_exosip_fix_route(op);
85         eXosip_lock();
86         eXosip_subscribe_build_initial_request(&msg,sal_op_get_to(op),sal_op_get_from(op),
87                 sal_op_get_route(op),"presence",600);
88         op->sid=eXosip_subscribe_send_initial_request(msg);
89         eXosip_unlock();
90         if (op->sid==-1){
91                 osip_message_free(msg);
92                 return -1;
93         }
94         sal_add_out_subscribe(op->base.root,op);
95         return 0;
96 }
97
98 int sal_unsubscribe(SalOp *op){
99         osip_message_t *msg=NULL;
100         if (op->did==-1){
101                 ms_error("cannot unsubscribe, no dialog !");
102                 return -1;
103         }
104         eXosip_lock();
105         eXosip_subscribe_build_refresh_request(op->did,&msg);
106         if (msg){
107                 osip_message_set_expires(msg,"0");
108                 eXosip_subscribe_send_refresh_request(op->did,msg);
109         }else ms_error("Could not build subscribe refresh request ! op->sid=%i, op->did=%i",
110                 op->sid,op->did);
111         eXosip_unlock();
112         return 0;
113 }
114
115 int sal_subscribe_accept(SalOp *op){
116         osip_message_t *msg;
117         eXosip_lock();
118         eXosip_insubscription_build_answer(op->tid,200,&msg);
119         eXosip_insubscription_send_answer(op->tid,200,msg);
120         eXosip_unlock();
121         return 0;
122 }
123
124 int sal_subscribe_decline(SalOp *op){
125         eXosip_lock();
126         eXosip_insubscription_send_answer(op->tid,401,NULL);
127         eXosip_unlock();
128         return 0;
129 }
130
131 static void add_presence_body(osip_message_t *notify, SalPresenceStatus online_status)
132 {
133         char buf[1000];
134 #ifdef SUPPORT_MSN
135         int atom_id = 1000;
136 #endif
137         char *contact_info;
138
139         osip_contact_t *ct=NULL;
140         osip_message_get_contact(notify,0,&ct);
141         osip_contact_to_str(ct,&contact_info);
142
143 #ifdef SUPPORT_MSN
144
145   if (online_status==SalPresenceOnline)
146     {
147       sprintf(buf, "<?xml version=\"1.0\"?>\n\
148 <!DOCTYPE presence\n\
149 PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
150 <presence>\n\
151 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
152 <atom id=\"%i\">\n\
153 <address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
154 <status status=\"open\" />\n\
155 <msnsubstatus substatus=\"online\" />\n\
156 </address>\n\
157 </atom>\n\
158 </presence>", contact_info, atom_id, contact_info);
159
160     }
161   else if (online_status==SalPresenceBusy)
162     {
163       sprintf(buf, "<?xml version=\"1.0\"?>\n\
164 <!DOCTYPE presence\n\
165 PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
166 <presence>\n\
167 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
168 <atom id=\"%i\">\n\
169 <address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
170 <status status=\"inuse\" />\n\
171 <msnsubstatus substatus=\"busy\" />\n\
172 </address>\n\
173 </atom>\n\
174 </presence>", contact_info, atom_id, contact_info);
175
176     }
177   else if (online_status==SalPresenceBerightback)
178     {
179       sprintf(buf, "<?xml version=\"1.0\"?>\n\
180 <!DOCTYPE presence\n\
181 PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
182 <presence>\n\
183 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
184 <atom id=\"%i\">\n\
185 <address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
186 <status status=\"inactive\" />\n\
187 <msnsubstatus substatus=\"berightback\" />\n\
188 </address>\n\
189 </atom>\n\
190 </presence>", contact_info, atom_id, contact_info);
191
192     }
193   else if (online_status==SalPresenceAway)
194     {
195       sprintf(buf, "<?xml version=\"1.0\"?>\n\
196 <!DOCTYPE presence\n\
197 PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
198 <presence>\n\
199 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
200 <atom id=\"%i\">\n\
201 <address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
202 <status status=\"inactive\" />\n\
203 <msnsubstatus substatus=\"away\" />\n\
204 </address>\n\
205 </atom>\n\
206 </presence>", contact_info, atom_id, contact_info);
207
208     }
209   else if (online_status==SalPresenceOnthephone)
210     {
211       sprintf(buf, "<?xml version=\"1.0\"?>\n\
212 <!DOCTYPE presence\n\
213 PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
214 <presence>\n\
215 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
216 <atom id=\"%i\">\n\
217 <address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
218 <status status=\"inuse\" />\n\
219 <msnsubstatus substatus=\"onthephone\" />\n\
220 </address>\n\
221 </atom>\n\
222 </presence>", contact_info, atom_id, contact_info);
223
224     }
225   else if (online_status==SalPresenceOuttolunch)
226     {
227       sprintf(buf, "<?xml version=\"1.0\"?>\n\
228 <!DOCTYPE presence\n\
229 PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
230 <presence>\n\
231 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
232 <atom id=\"%i\">\n\
233 <address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
234 <status status=\"inactive\" />\n\
235 <msnsubstatus substatus=\"outtolunch\" />\n\
236 </address>\n\
237 </atom>\n\
238 </presence>", contact_info, atom_id, contact_info);
239
240     }
241   else
242     {
243       sprintf(buf, "<?xml version=\"1.0\"?>\n\
244 <!DOCTYPE presence\n\
245 PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
246 <presence>\n\
247 <presentity uri=\"%s;method=SUBSCRIBE\" />\n\
248 <atom id=\"%i\">\n\
249 <address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
250 <status status=\"inactive\" />\n\
251 <msnsubstatus substatus=\"away\" />\n\
252 </address>\n\
253 </atom>\n\
254 </presence>", contact_info, atom_id, contact_info);
255     }
256
257   osip_message_set_body(notify, buf, strlen(buf));
258   osip_message_set_content_type(notify, "application/xpidf+xml");
259 #else
260
261   if (online_status==SalPresenceOnline)
262     {
263       sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
264 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
265           entity=\"%s\">\n\
266 <tuple id=\"sg89ae\">\n\
267 <status>\n\
268 <basic>open</basic>\n\
269 </status>\n\
270 <contact priority=\"0.8\">%s</contact>\n\
271 <note>online</note>\n\
272 </tuple>\n\
273 </presence>",
274               contact_info, contact_info);
275     }
276   else if (online_status==SalPresenceBusy)
277     {
278       sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
279 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
280           xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
281           entity=\"%s\">\n\
282 <tuple id=\"sg89ae\">\n\
283 <status>\n\
284 <basic>open</basic>\n\
285 <es:activities>\n\
286   <es:activity>busy</es:activity>\n\
287 </es:activities>\n\
288 </status>\n\
289 <contact priority=\"0.8\">%s</contact>\n\
290 <note>busy</note>\n\
291 </tuple>\n\
292 </presence>",
293               contact_info, contact_info);
294     }
295   else if (online_status==SalPresenceBerightback)
296     {
297       sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
298 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
299           xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
300           entity=\"%s\">\n\
301 <tuple id=\"sg89ae\">\n\
302 <status>\n\
303 <basic>open</basic>\n\
304 <es:activities>\n\
305   <es:activity>in-transit</es:activity>\n\
306 </es:activities>\n\
307 </status>\n\
308 <contact priority=\"0.8\">%s</contact>\n\
309 <note>be right back</note>\n\
310 </tuple>\n\
311 </presence>",
312               contact_info, contact_info);
313     }
314   else if (online_status==SalPresenceAway)
315     {
316       sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
317 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
318           xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
319           entity=\"%s\">\n\
320 <tuple id=\"sg89ae\">\n\
321 <status>\n\
322 <basic>open</basic>\n\
323 <es:activities>\n\
324   <es:activity>away</es:activity>\n\
325 </es:activities>\n\
326 </status>\n\
327 <contact priority=\"0.8\">%s</contact>\n\
328 <note>away</note>\n\
329 </tuple>\n\
330 </presence>",
331               contact_info, contact_info);
332     }
333   else if (online_status==SalPresenceOnthephone)
334     {
335       sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
336 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
337           xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
338           entity=\"%s\">\n\
339 <tuple id=\"sg89ae\">\n\
340 <status>\n\
341 <basic>open</basic>\n\
342 <es:activities>\n\
343   <es:activity>on-the-phone</es:activity>\n\
344 </es:activities>\n\
345 </status>\n\
346 <contact priority=\"0.8\">%s</contact>\n\
347 <note>on the phone</note>\n\
348 </tuple>\n\
349 </presence>",
350               contact_info, contact_info);
351     }
352   else if (online_status==SalPresenceOuttolunch)
353     {
354       sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
355 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
356           xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
357           entity=\"%s\">\n\
358 <tuple id=\"sg89ae\">\n\
359 <status>\n\
360 <basic>open</basic>\n\
361 <es:activities>\n\
362   <es:activity>meal</es:activity>\n\
363 </es:activities>\n\
364 </status>\n\
365 <contact priority=\"0.8\">%s</contact>\n\
366 <note>out to lunch</note>\n\
367 </tuple>\n\
368 </presence>",
369               contact_info, contact_info);
370     }
371   else
372     {
373       /* */
374       sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
375 <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
376 xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
377 entity=\"%s\">\n%s",
378               contact_info,
379 "<tuple id=\"sg89ae\">\n\
380 <status>\n\
381 <basic>closed</basic>\n\
382 <es:activities>\n\
383   <es:activity>permanent-absence</es:activity>\n\
384 </es:activities>\n\
385 </status>\n\
386 </tuple>\n\
387 \n</presence>\n");
388     }
389   osip_message_set_body(notify, buf, strlen(buf));
390   osip_message_set_content_type(notify, "application/pidf+xml");
391
392 #endif
393         osip_free(contact_info);
394 }
395
396
397 int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message){
398         osip_message_t *msg;
399         eXosip_ss_t ss=EXOSIP_SUBCRSTATE_ACTIVE;
400         if (op->nid==-1){
401                 ms_warning("Cannot notify, subscription was closed.");
402                 return -1;
403         }
404         
405         eXosip_lock();
406         eXosip_insubscription_build_notify(op->did,ss,DEACTIVATED,&msg);
407         if (msg!=NULL){
408                 const char *identity=sal_op_get_contact(op);
409                 if (identity==NULL) identity=sal_op_get_to(op);
410                 osip_message_set_contact(msg,identity);
411                 add_presence_body(msg,status);
412                 eXosip_insubscription_send_request(op->did,msg);
413         }else ms_error("could not create notify for incoming subscription.");
414         eXosip_unlock();
415         return 0;
416 }
417
418 int sal_notify_close(SalOp *op){
419         osip_message_t *msg=NULL;
420         eXosip_lock();
421         eXosip_insubscription_build_notify(op->did,EXOSIP_SUBCRSTATE_TERMINATED,DEACTIVATED,&msg);
422         if (msg!=NULL){
423                 const char *identity=sal_op_get_contact(op);
424                 if (identity==NULL) identity=sal_op_get_to(op);
425                 osip_message_set_contact(msg,identity);
426                 eXosip_insubscription_send_request(op->did,msg);
427         }else ms_error("sal_notify_close(): could not create notify for incoming subscription"
428             " did=%i, nid=%i",op->did,op->nid);
429         eXosip_unlock();
430         return 0;
431 }
432
433 int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus presence_mode){
434         osip_message_t *pub;
435         int i;
436         char buf[1024];
437
438         if (presence_mode==SalPresenceOnline)
439         {
440           snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
441         <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
442                   entity=\"%s\">\n\
443         <tuple id=\"sg89ae\">\n\
444         <status>\n\
445         <basic>open</basic>\n\
446         </status>\n\
447         <contact priority=\"0.8\">%s</contact>\n\
448         <note>online</note>\n\
449         </tuple>\n\
450         </presence>",
451                    from, from);
452         }
453         else if (presence_mode==SalPresenceBusy
454            ||presence_mode==SalPresenceDonotdisturb)
455         {
456           snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
457         <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
458                   xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
459                   entity=\"%s\">\n\
460         <tuple id=\"sg89ae\">\n\
461         <status>\n\
462         <basic>open</basic>\n\
463         <es:activities>\n\
464         <es:activity>busy</es:activity>\n\
465         </es:activities>\n\
466         </status>\n\
467         <contact priority=\"0.8\">%s</contact>\n\
468         <note>busy</note>\n\
469         </tuple>\n\
470         </presence>",
471                   from, from);
472         }
473         else if (presence_mode==SalPresenceBerightback)
474         {
475                 snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
476         <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
477                   xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
478                   entity=\"%s\">\n\
479         <tuple id=\"sg89ae\">\n\
480         <status>\n\
481         <basic>open</basic>\n\
482         <es:activities>\n\
483         <es:activity>in-transit</es:activity>\n\
484         </es:activities>\n\
485         </status>\n\
486         <contact priority=\"0.8\">%s</contact>\n\
487         <note>be right back</note>\n\
488         </tuple>\n\
489         </presence>",
490                   from,from);
491         }
492         else if (presence_mode==SalPresenceAway
493            ||presence_mode==SalPresenceMoved)
494         {
495                 snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
496         <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
497                   xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
498                   entity=\"%s\">\n\
499         <tuple id=\"sg89ae\">\n\
500         <status>\n\
501         <basic>open</basic>\n\
502         <es:activities>\n\
503         <es:activity>away</es:activity>\n\
504         </es:activities>\n\
505         </status>\n\
506         <contact priority=\"0.8\">%s</contact>\n\
507         <note>away</note>\n\
508         </tuple>\n\
509         </presence>",
510                   from, from);
511         }
512         else if (presence_mode==SalPresenceOnthephone)
513         {
514           snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
515         <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
516                   xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
517                   entity=\"%s\">\n\
518         <tuple id=\"sg89ae\">\n\
519         <status>\n\
520         <basic>open</basic>\n\
521         <es:activities>\n\
522         <es:activity>on-the-phone</es:activity>\n\
523         </es:activities>\n\
524         </status>\n\
525         <contact priority=\"0.8\">%s</contact>\n\
526         <note>on the phone</note>\n\
527         </tuple>\n\
528         </presence>",
529                   from, from);
530         }
531         else if (presence_mode==SalPresenceOuttolunch)
532         {
533           snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
534         <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
535                   xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
536                   entity=\"%s\">\n\
537         <tuple id=\"sg89ae\">\n\
538         <status>\n\
539         <basic>open</basic>\n\
540         <es:activities>\n\
541         <es:activity>meal</es:activity>\n\
542         </es:activities>\n\
543         </status>\n\
544         <contact priority=\"0.8\">%s</contact>\n\
545         <note>out to lunch</note>\n\
546         </tuple>\n\
547         </presence>",
548                   from, from);
549         }
550         else{ 
551           /* offline */
552           snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
553         <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
554         xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
555         entity=\"%s\">\n%s",
556                   from,
557         "<tuple id=\"sg89ae\">\n\
558         <status>\n\
559         <basic>closed</basic>\n\
560         <es:activities>\n\
561         <es:activity>permanent-absence</e:activity>\n\
562         </es:activities>\n\
563         </status>\n\
564         </tuple>\n\
565         \n</presence>\n");
566         }
567
568         i = eXosip_build_publish(&pub,from, to, NULL, "presence", "1800", "application/pidf+xml", buf);
569         if (i<0){
570                 ms_warning("Failed to build publish request.");
571                 return -1;
572         }
573
574         eXosip_lock();
575         i = eXosip_publish(pub, to); /* should update the sip-if-match parameter
576                                     from sip-etag  from last 200ok of PUBLISH */
577         eXosip_unlock();
578         if (i<0){
579           ms_message("Failed to send publish request.");
580           return -1;
581         }
582         return 0;
583 }
584
585 void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){
586         SalOp *op=sal_op_new(sal);
587         char *tmp;
588         op->did=ev->did;
589         op->tid=ev->tid;
590         op->nid=ev->nid;
591         osip_from_to_str(ev->request->from,&tmp);
592         sal_op_set_from(op,tmp);
593         ms_free(tmp);
594         osip_from_to_str(ev->request->to,&tmp);
595         sal_op_set_to(op,tmp);
596         ms_free(tmp);
597         sal_add_in_subscribe(sal,op);
598         sal->callbacks.subscribe_received(op,sal_op_get_from(op));
599 }
600
601 void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){
602         SalOp *op=sal_find_out_subscribe(sal,ev->sid);
603         char *tmp;
604         osip_from_t *from=NULL;
605         osip_body_t *body=NULL;
606         SalPresenceStatus estatus=SalPresenceOffline;
607         
608         ms_message("Receiving notify with sid=%i,nid=%i",ev->sid,ev->nid);
609
610         if (op==NULL){
611                 ms_error("No operation related to this notify !");
612                 return;
613         }
614         if (ev->request==NULL) return;
615
616         from=ev->request->from;
617         osip_message_get_body(ev->request,0,&body);
618         if (body==NULL){
619                 ms_error("No body in NOTIFY");
620                 return;
621         }
622         osip_from_to_str(from,&tmp);
623         if (strstr(body->body,"pending")!=NULL){
624                 estatus=SalPresenceOffline;
625         }else if (strstr(body->body,"busy")!=NULL){
626                 estatus=SalPresenceBusy;
627         }else if (strstr(body->body,"berightback")!=NULL
628                         || strstr(body->body,"in-transit")!=NULL ){
629                 estatus=SalPresenceBerightback;
630         }else if (strstr(body->body,"away")!=NULL){
631                 estatus=SalPresenceAway;
632         }else if (strstr(body->body,"onthephone")!=NULL
633                 || strstr(body->body,"on-the-phone")!=NULL){
634                 estatus=SalPresenceOnthephone;
635         }else if (strstr(body->body,"outtolunch")!=NULL
636                         || strstr(body->body,"meal")!=NULL){
637                 estatus=SalPresenceOuttolunch;
638         }else if (strstr(body->body,"closed")!=NULL){
639                 estatus=SalPresenceOffline;
640         }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) {
641                 estatus=SalPresenceOnline;
642         }else{
643                 estatus=SalPresenceOffline;
644         }
645         ms_message("We are notified that %s has online status %i",tmp,estatus);
646         if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) {
647                 sal_remove_out_subscribe(sal,op);
648                 op->sid=-1;
649                 op->did=-1;
650                 ms_message("And outgoing subscription terminated by remote.");
651         }
652         sal->callbacks.notify(op,op->sid!=-1 ? SalSubscribeActive : SalSubscribeTerminated, estatus,NULL);
653         osip_free(tmp);
654 }
655
656 void sal_exosip_subscription_answered(Sal *sal,eXosip_event_t *ev){
657         SalOp *op=sal_find_out_subscribe(sal,ev->sid);
658         if (op==NULL){
659                 ms_error("Subscription answered but no associated op !");
660                 return;
661         }
662         op->did=ev->did;
663 }
664
665 void sal_exosip_in_subscription_closed(Sal *sal, eXosip_event_t *ev){
666         SalOp *op=sal_find_in_subscribe(sal,ev->nid);
667         char *tmp;
668         if (op==NULL){
669                 ms_error("Incoming subscription closed but no associated op !");
670                 return;
671         }
672         
673         
674         sal_remove_in_subscribe(sal,op);
675         op->nid=-1;
676         op->did=-1;
677         if (ev->request){
678                 osip_from_to_str(ev->request->from,&tmp);
679                 sal->callbacks.subscribe_closed(op,tmp);
680                 osip_free(tmp);
681         }
682 }
683
684 void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev){
685         SalOp *op=sal_find_out_subscribe(sal,ev->sid);
686         if (op==NULL){
687                 ms_error("Subscription closed but no associated op !");
688                 return;
689         }
690         sal_remove_out_subscribe(sal,op);
691         op->sid=-1;
692         op->did=-1;
693         sal->callbacks.notify(op,SalSubscribeTerminated, SalPresenceOffline,NULL);
694 }
695
696